@fluidframework/merge-tree 2.1.0-276985 → 2.1.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 (524) hide show
  1. package/.eslintrc.cjs +2 -4
  2. package/CHANGELOG.md +15 -0
  3. package/README.md +109 -1
  4. package/api-extractor/api-extractor.current.json +5 -0
  5. package/api-extractor/api-extractor.legacy.json +1 -1
  6. package/api-extractor.json +1 -1
  7. package/api-report/merge-tree.legacy.alpha.api.md +10 -22
  8. package/api-report/merge-tree.legacy.public.api.md +9 -0
  9. package/dist/MergeTreeTextHelper.d.ts.map +1 -1
  10. package/dist/MergeTreeTextHelper.js +1 -1
  11. package/dist/MergeTreeTextHelper.js.map +1 -1
  12. package/dist/attributionCollection.d.ts.map +1 -1
  13. package/dist/attributionCollection.js +65 -17
  14. package/dist/attributionCollection.js.map +1 -1
  15. package/dist/attributionPolicy.d.ts +2 -1
  16. package/dist/attributionPolicy.d.ts.map +1 -1
  17. package/dist/attributionPolicy.js +10 -3
  18. package/dist/attributionPolicy.js.map +1 -1
  19. package/dist/client.d.ts +3 -1
  20. package/dist/client.d.ts.map +1 -1
  21. package/dist/client.js +65 -37
  22. package/dist/client.js.map +1 -1
  23. package/dist/collections/list.d.ts.map +1 -1
  24. package/dist/collections/list.js +5 -2
  25. package/dist/collections/list.js.map +1 -1
  26. package/dist/collections/rbTree.d.ts +2 -2
  27. package/dist/collections/rbTree.d.ts.map +1 -1
  28. package/dist/collections/rbTree.js +23 -35
  29. package/dist/collections/rbTree.js.map +1 -1
  30. package/dist/endOfTreeSegment.d.ts.map +1 -1
  31. package/dist/endOfTreeSegment.js +4 -1
  32. package/dist/endOfTreeSegment.js.map +1 -1
  33. package/dist/legacy.d.ts +1 -1
  34. package/dist/localReference.d.ts +16 -6
  35. package/dist/localReference.d.ts.map +1 -1
  36. package/dist/localReference.js +31 -20
  37. package/dist/localReference.js.map +1 -1
  38. package/dist/mergeTree.d.ts +0 -1
  39. package/dist/mergeTree.d.ts.map +1 -1
  40. package/dist/mergeTree.js +127 -112
  41. package/dist/mergeTree.js.map +1 -1
  42. package/dist/mergeTreeNodeWalk.d.ts.map +1 -1
  43. package/dist/mergeTreeNodeWalk.js +1 -1
  44. package/dist/mergeTreeNodeWalk.js.map +1 -1
  45. package/dist/mergeTreeNodes.d.ts +6 -5
  46. package/dist/mergeTreeNodes.d.ts.map +1 -1
  47. package/dist/mergeTreeNodes.js +29 -20
  48. package/dist/mergeTreeNodes.js.map +1 -1
  49. package/dist/mergeTreeTracking.js +3 -3
  50. package/dist/mergeTreeTracking.js.map +1 -1
  51. package/dist/opBuilder.d.ts +6 -1
  52. package/dist/opBuilder.d.ts.map +1 -1
  53. package/dist/opBuilder.js +5 -0
  54. package/dist/opBuilder.js.map +1 -1
  55. package/dist/ops.d.ts.map +1 -1
  56. package/dist/ops.js.map +1 -1
  57. package/dist/ordinal.d.ts.map +1 -1
  58. package/dist/ordinal.js +7 -0
  59. package/dist/ordinal.js.map +1 -1
  60. package/dist/partialLengths.d.ts +4 -2
  61. package/dist/partialLengths.d.ts.map +1 -1
  62. package/dist/partialLengths.js +101 -53
  63. package/dist/partialLengths.js.map +1 -1
  64. package/dist/perspective.d.ts +4 -1
  65. package/dist/perspective.d.ts.map +1 -1
  66. package/dist/perspective.js +7 -6
  67. package/dist/perspective.js.map +1 -1
  68. package/dist/properties.d.ts +13 -10
  69. package/dist/properties.d.ts.map +1 -1
  70. package/dist/properties.js +22 -11
  71. package/dist/properties.js.map +1 -1
  72. package/dist/public.d.ts +1 -1
  73. package/dist/referencePositions.d.ts +7 -0
  74. package/dist/referencePositions.d.ts.map +1 -1
  75. package/dist/referencePositions.js +7 -0
  76. package/dist/referencePositions.js.map +1 -1
  77. package/dist/revertibles.d.ts +6 -0
  78. package/dist/revertibles.d.ts.map +1 -1
  79. package/dist/revertibles.js +50 -21
  80. package/dist/revertibles.js.map +1 -1
  81. package/dist/segmentGroupCollection.d.ts.map +1 -1
  82. package/dist/segmentGroupCollection.js +2 -0
  83. package/dist/segmentGroupCollection.js.map +1 -1
  84. package/dist/segmentPropertiesManager.d.ts +7 -3
  85. package/dist/segmentPropertiesManager.d.ts.map +1 -1
  86. package/dist/segmentPropertiesManager.js +20 -15
  87. package/dist/segmentPropertiesManager.js.map +1 -1
  88. package/dist/snapshotChunks.d.ts.map +1 -1
  89. package/dist/snapshotChunks.js +10 -5
  90. package/dist/snapshotChunks.js.map +1 -1
  91. package/dist/snapshotLoader.d.ts.map +1 -1
  92. package/dist/snapshotLoader.js +14 -10
  93. package/dist/snapshotLoader.js.map +1 -1
  94. package/dist/snapshotV1.d.ts.map +1 -1
  95. package/dist/snapshotV1.js +20 -8
  96. package/dist/snapshotV1.js.map +1 -1
  97. package/dist/snapshotlegacy.d.ts.map +1 -1
  98. package/dist/snapshotlegacy.js +4 -2
  99. package/dist/snapshotlegacy.js.map +1 -1
  100. package/dist/sortedSegmentSet.d.ts.map +1 -1
  101. package/dist/sortedSegmentSet.js +8 -1
  102. package/dist/sortedSegmentSet.js.map +1 -1
  103. package/dist/sortedSet.d.ts.map +1 -1
  104. package/dist/sortedSet.js +4 -0
  105. package/dist/sortedSet.js.map +1 -1
  106. package/dist/test/Insertion.perf.spec.js.map +1 -1
  107. package/dist/test/Removal.perf.spec.js.map +1 -1
  108. package/dist/test/Snapshot.perf.spec.js +1 -0
  109. package/dist/test/Snapshot.perf.spec.js.map +1 -1
  110. package/dist/test/attributionCollection.perf.spec.js +3 -1
  111. package/dist/test/attributionCollection.perf.spec.js.map +1 -1
  112. package/dist/test/attributionCollection.spec.js +69 -68
  113. package/dist/test/attributionCollection.spec.js.map +1 -1
  114. package/dist/test/attributionPolicy.spec.js +29 -27
  115. package/dist/test/attributionPolicy.spec.js.map +1 -1
  116. package/dist/test/beastTest.spec.d.ts +1 -4
  117. package/dist/test/beastTest.spec.d.ts.map +1 -1
  118. package/dist/test/beastTest.spec.js +32 -30
  119. package/dist/test/beastTest.spec.js.map +1 -1
  120. package/dist/test/client.annotateMarker.spec.js +5 -5
  121. package/dist/test/client.annotateMarker.spec.js.map +1 -1
  122. package/dist/test/client.apis.spec.d.ts.map +1 -1
  123. package/dist/test/client.apis.spec.js +5 -7
  124. package/dist/test/client.apis.spec.js.map +1 -1
  125. package/dist/test/client.applyMsg.spec.js +125 -103
  126. package/dist/test/client.applyMsg.spec.js.map +1 -1
  127. package/dist/test/client.applyStashedOpFarm.spec.js +18 -10
  128. package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
  129. package/dist/test/client.attributionFarm.spec.js +13 -8
  130. package/dist/test/client.attributionFarm.spec.js.map +1 -1
  131. package/dist/test/client.conflictFarm.spec.js +4 -2
  132. package/dist/test/client.conflictFarm.spec.js.map +1 -1
  133. package/dist/test/client.getPosition.spec.js +10 -10
  134. package/dist/test/client.getPosition.spec.js.map +1 -1
  135. package/dist/test/client.localReference.spec.js +111 -104
  136. package/dist/test/client.localReference.spec.js.map +1 -1
  137. package/dist/test/client.localReferenceFarm.spec.js +14 -10
  138. package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
  139. package/dist/test/client.rebasePosition.spec.js +12 -12
  140. package/dist/test/client.rebasePosition.spec.js.map +1 -1
  141. package/dist/test/client.reconnectFarm.spec.js +12 -9
  142. package/dist/test/client.reconnectFarm.spec.js.map +1 -1
  143. package/dist/test/client.replay.spec.js +11 -10
  144. package/dist/test/client.replay.spec.js.map +1 -1
  145. package/dist/test/client.rollback.spec.js +87 -84
  146. package/dist/test/client.rollback.spec.js.map +1 -1
  147. package/dist/test/client.rollbackFarm.spec.js +3 -1
  148. package/dist/test/client.rollbackFarm.spec.js.map +1 -1
  149. package/dist/test/client.searchForMarker.spec.js +122 -112
  150. package/dist/test/client.searchForMarker.spec.js.map +1 -1
  151. package/dist/test/client.walkSegments.spec.js +7 -7
  152. package/dist/test/client.walkSegments.spec.js.map +1 -1
  153. package/dist/test/collections.list.spec.js +14 -14
  154. package/dist/test/collections.list.spec.js.map +1 -1
  155. package/dist/test/createInsertOnlyAttributionPolicy.spec.js +3 -3
  156. package/dist/test/createInsertOnlyAttributionPolicy.spec.js.map +1 -1
  157. package/dist/test/dirname.cjs +1 -0
  158. package/dist/test/dirname.cjs.map +1 -1
  159. package/dist/test/dirname.d.cts.map +1 -1
  160. package/dist/test/mergeTree.annotate.deltaCallback.spec.js +7 -7
  161. package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  162. package/dist/test/mergeTree.annotate.spec.js +87 -87
  163. package/dist/test/mergeTree.annotate.spec.js.map +1 -1
  164. package/dist/test/mergeTree.insert.deltaCallback.spec.js +6 -6
  165. package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  166. package/dist/test/mergeTree.insertingWalk.spec.js +24 -24
  167. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
  168. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +6 -6
  169. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  170. package/dist/test/mergeTree.markRangeRemoved.spec.js +23 -23
  171. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  172. package/dist/test/mergeTree.walk.spec.js +3 -3
  173. package/dist/test/mergeTree.walk.spec.js.map +1 -1
  174. package/dist/test/mergeTree.zamboni.spec.js +10 -10
  175. package/dist/test/mergeTree.zamboni.spec.js.map +1 -1
  176. package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
  177. package/dist/test/mergeTreeOperationRunner.js +28 -16
  178. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  179. package/dist/test/mergeTreeOperationRunner.spec.js +9 -5
  180. package/dist/test/mergeTreeOperationRunner.spec.js.map +1 -1
  181. package/dist/test/obliterate.concurrent.spec.js +165 -165
  182. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  183. package/dist/test/obliterate.deltaCallback.spec.js +20 -21
  184. package/dist/test/obliterate.deltaCallback.spec.js.map +1 -1
  185. package/dist/test/obliterate.partialLength.spec.js +7 -7
  186. package/dist/test/obliterate.partialLength.spec.js.map +1 -1
  187. package/dist/test/obliterate.reconnect.spec.js +13 -13
  188. package/dist/test/obliterate.reconnect.spec.js.map +1 -1
  189. package/dist/test/obliterate.spec.js +9 -9
  190. package/dist/test/obliterate.spec.js.map +1 -1
  191. package/dist/test/ordinal.spec.js +10 -4
  192. package/dist/test/ordinal.spec.js.map +1 -1
  193. package/dist/test/partialLength.spec.js.map +1 -1
  194. package/dist/test/properties.spec.js +15 -15
  195. package/dist/test/properties.spec.js.map +1 -1
  196. package/dist/test/reconnectHelper.d.ts +4 -4
  197. package/dist/test/reconnectHelper.d.ts.map +1 -1
  198. package/dist/test/reconnectHelper.js +28 -20
  199. package/dist/test/reconnectHelper.js.map +1 -1
  200. package/dist/test/resetPendingSegmentsToOp.spec.js +35 -29
  201. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  202. package/dist/test/revertibleFarm.spec.js +11 -10
  203. package/dist/test/revertibleFarm.spec.js.map +1 -1
  204. package/dist/test/revertibles.spec.d.ts.map +1 -1
  205. package/dist/test/revertibles.spec.js +96 -57
  206. package/dist/test/revertibles.spec.js.map +1 -1
  207. package/dist/test/segmentGroupCollection.spec.js +17 -17
  208. package/dist/test/segmentGroupCollection.spec.js.map +1 -1
  209. package/dist/test/snapshot.spec.js +5 -5
  210. package/dist/test/snapshot.spec.js.map +1 -1
  211. package/dist/test/snapshot.utils.d.ts.map +1 -1
  212. package/dist/test/snapshot.utils.js +6 -6
  213. package/dist/test/snapshot.utils.js.map +1 -1
  214. package/dist/test/snapshotlegacy.spec.js +18 -13
  215. package/dist/test/snapshotlegacy.spec.js.map +1 -1
  216. package/dist/test/sortedSegmentSet.spec.js +22 -18
  217. package/dist/test/sortedSegmentSet.spec.js.map +1 -1
  218. package/dist/test/testClient.d.ts +6 -5
  219. package/dist/test/testClient.d.ts.map +1 -1
  220. package/dist/test/testClient.js +30 -32
  221. package/dist/test/testClient.js.map +1 -1
  222. package/dist/test/testClientLogger.d.ts.map +1 -1
  223. package/dist/test/testClientLogger.js +39 -38
  224. package/dist/test/testClientLogger.js.map +1 -1
  225. package/dist/test/testSerializer.d.ts +5 -5
  226. package/dist/test/testSerializer.d.ts.map +1 -1
  227. package/dist/test/testSerializer.js +0 -1
  228. package/dist/test/testSerializer.js.map +1 -1
  229. package/dist/test/testServer.d.ts.map +1 -1
  230. package/dist/test/testServer.js.map +1 -1
  231. package/dist/test/testUtils.d.ts +1 -1
  232. package/dist/test/testUtils.d.ts.map +1 -1
  233. package/dist/test/testUtils.js +15 -17
  234. package/dist/test/testUtils.js.map +1 -1
  235. package/dist/test/text.d.ts.map +1 -1
  236. package/dist/test/text.js +1 -1
  237. package/dist/test/text.js.map +1 -1
  238. package/dist/test/tracking.spec.js +50 -46
  239. package/dist/test/tracking.spec.js.map +1 -1
  240. package/dist/test/wordUnitTests.spec.d.ts.map +1 -1
  241. package/dist/test/wordUnitTests.spec.js +10 -10
  242. package/dist/test/wordUnitTests.spec.js.map +1 -1
  243. package/dist/textSegment.d.ts +1 -1
  244. package/dist/textSegment.d.ts.map +1 -1
  245. package/dist/textSegment.js +3 -3
  246. package/dist/textSegment.js.map +1 -1
  247. package/dist/zamboni.d.ts.map +1 -1
  248. package/dist/zamboni.js +7 -2
  249. package/dist/zamboni.js.map +1 -1
  250. package/internal.d.ts +1 -1
  251. package/legacy.d.ts +1 -1
  252. package/lib/MergeTreeTextHelper.d.ts.map +1 -1
  253. package/lib/MergeTreeTextHelper.js +1 -1
  254. package/lib/MergeTreeTextHelper.js.map +1 -1
  255. package/lib/attributionCollection.d.ts.map +1 -1
  256. package/lib/attributionCollection.js +65 -17
  257. package/lib/attributionCollection.js.map +1 -1
  258. package/lib/attributionPolicy.d.ts +2 -1
  259. package/lib/attributionPolicy.d.ts.map +1 -1
  260. package/lib/attributionPolicy.js +10 -3
  261. package/lib/attributionPolicy.js.map +1 -1
  262. package/lib/client.d.ts +3 -1
  263. package/lib/client.d.ts.map +1 -1
  264. package/lib/client.js +65 -37
  265. package/lib/client.js.map +1 -1
  266. package/lib/collections/list.d.ts.map +1 -1
  267. package/lib/collections/list.js +5 -2
  268. package/lib/collections/list.js.map +1 -1
  269. package/lib/collections/rbTree.d.ts +2 -2
  270. package/lib/collections/rbTree.d.ts.map +1 -1
  271. package/lib/collections/rbTree.js +23 -35
  272. package/lib/collections/rbTree.js.map +1 -1
  273. package/lib/endOfTreeSegment.d.ts.map +1 -1
  274. package/lib/endOfTreeSegment.js +4 -1
  275. package/lib/endOfTreeSegment.js.map +1 -1
  276. package/lib/legacy.d.ts +1 -1
  277. package/lib/localReference.d.ts +16 -6
  278. package/lib/localReference.d.ts.map +1 -1
  279. package/lib/localReference.js +31 -20
  280. package/lib/localReference.js.map +1 -1
  281. package/lib/mergeTree.d.ts +0 -1
  282. package/lib/mergeTree.d.ts.map +1 -1
  283. package/lib/mergeTree.js +127 -112
  284. package/lib/mergeTree.js.map +1 -1
  285. package/lib/mergeTreeNodeWalk.d.ts.map +1 -1
  286. package/lib/mergeTreeNodeWalk.js +1 -1
  287. package/lib/mergeTreeNodeWalk.js.map +1 -1
  288. package/lib/mergeTreeNodes.d.ts +6 -5
  289. package/lib/mergeTreeNodes.d.ts.map +1 -1
  290. package/lib/mergeTreeNodes.js +29 -20
  291. package/lib/mergeTreeNodes.js.map +1 -1
  292. package/lib/mergeTreeTracking.js +3 -3
  293. package/lib/mergeTreeTracking.js.map +1 -1
  294. package/lib/opBuilder.d.ts +6 -1
  295. package/lib/opBuilder.d.ts.map +1 -1
  296. package/lib/opBuilder.js +5 -0
  297. package/lib/opBuilder.js.map +1 -1
  298. package/lib/ops.d.ts.map +1 -1
  299. package/lib/ops.js.map +1 -1
  300. package/lib/ordinal.d.ts.map +1 -1
  301. package/lib/ordinal.js +7 -0
  302. package/lib/ordinal.js.map +1 -1
  303. package/lib/partialLengths.d.ts +4 -2
  304. package/lib/partialLengths.d.ts.map +1 -1
  305. package/lib/partialLengths.js +101 -53
  306. package/lib/partialLengths.js.map +1 -1
  307. package/lib/perspective.d.ts +4 -1
  308. package/lib/perspective.d.ts.map +1 -1
  309. package/lib/perspective.js +7 -6
  310. package/lib/perspective.js.map +1 -1
  311. package/lib/properties.d.ts +13 -10
  312. package/lib/properties.d.ts.map +1 -1
  313. package/lib/properties.js +22 -11
  314. package/lib/properties.js.map +1 -1
  315. package/lib/public.d.ts +1 -1
  316. package/lib/referencePositions.d.ts +7 -0
  317. package/lib/referencePositions.d.ts.map +1 -1
  318. package/lib/referencePositions.js +7 -0
  319. package/lib/referencePositions.js.map +1 -1
  320. package/lib/revertibles.d.ts +6 -0
  321. package/lib/revertibles.d.ts.map +1 -1
  322. package/lib/revertibles.js +50 -21
  323. package/lib/revertibles.js.map +1 -1
  324. package/lib/segmentGroupCollection.d.ts.map +1 -1
  325. package/lib/segmentGroupCollection.js +2 -0
  326. package/lib/segmentGroupCollection.js.map +1 -1
  327. package/lib/segmentPropertiesManager.d.ts +7 -3
  328. package/lib/segmentPropertiesManager.d.ts.map +1 -1
  329. package/lib/segmentPropertiesManager.js +20 -15
  330. package/lib/segmentPropertiesManager.js.map +1 -1
  331. package/lib/snapshotChunks.d.ts.map +1 -1
  332. package/lib/snapshotChunks.js +10 -5
  333. package/lib/snapshotChunks.js.map +1 -1
  334. package/lib/snapshotLoader.d.ts.map +1 -1
  335. package/lib/snapshotLoader.js +14 -10
  336. package/lib/snapshotLoader.js.map +1 -1
  337. package/lib/snapshotV1.d.ts.map +1 -1
  338. package/lib/snapshotV1.js +20 -8
  339. package/lib/snapshotV1.js.map +1 -1
  340. package/lib/snapshotlegacy.d.ts.map +1 -1
  341. package/lib/snapshotlegacy.js +4 -2
  342. package/lib/snapshotlegacy.js.map +1 -1
  343. package/lib/sortedSegmentSet.d.ts.map +1 -1
  344. package/lib/sortedSegmentSet.js +8 -1
  345. package/lib/sortedSegmentSet.js.map +1 -1
  346. package/lib/sortedSet.d.ts.map +1 -1
  347. package/lib/sortedSet.js +4 -0
  348. package/lib/sortedSet.js.map +1 -1
  349. package/lib/test/Insertion.perf.spec.js.map +1 -1
  350. package/lib/test/Removal.perf.spec.js.map +1 -1
  351. package/lib/test/Snapshot.perf.spec.js +1 -0
  352. package/lib/test/Snapshot.perf.spec.js.map +1 -1
  353. package/lib/test/attributionCollection.perf.spec.js +3 -1
  354. package/lib/test/attributionCollection.perf.spec.js.map +1 -1
  355. package/lib/test/attributionCollection.spec.js +3 -2
  356. package/lib/test/attributionCollection.spec.js.map +1 -1
  357. package/lib/test/attributionPolicy.spec.js +3 -1
  358. package/lib/test/attributionPolicy.spec.js.map +1 -1
  359. package/lib/test/beastTest.spec.d.ts +1 -4
  360. package/lib/test/beastTest.spec.d.ts.map +1 -1
  361. package/lib/test/beastTest.spec.js +26 -24
  362. package/lib/test/beastTest.spec.js.map +1 -1
  363. package/lib/test/client.annotateMarker.spec.js +1 -1
  364. package/lib/test/client.annotateMarker.spec.js.map +1 -1
  365. package/lib/test/client.apis.spec.d.ts.map +1 -1
  366. package/lib/test/client.apis.spec.js +4 -6
  367. package/lib/test/client.apis.spec.js.map +1 -1
  368. package/lib/test/client.applyMsg.spec.js +72 -50
  369. package/lib/test/client.applyMsg.spec.js.map +1 -1
  370. package/lib/test/client.applyStashedOpFarm.spec.js +18 -10
  371. package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
  372. package/lib/test/client.attributionFarm.spec.js +12 -7
  373. package/lib/test/client.attributionFarm.spec.js.map +1 -1
  374. package/lib/test/client.conflictFarm.spec.js +4 -2
  375. package/lib/test/client.conflictFarm.spec.js.map +1 -1
  376. package/lib/test/client.getPosition.spec.js +1 -1
  377. package/lib/test/client.getPosition.spec.js.map +1 -1
  378. package/lib/test/client.localReference.spec.js +14 -7
  379. package/lib/test/client.localReference.spec.js.map +1 -1
  380. package/lib/test/client.localReferenceFarm.spec.js +13 -9
  381. package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
  382. package/lib/test/client.rebasePosition.spec.js +1 -1
  383. package/lib/test/client.rebasePosition.spec.js.map +1 -1
  384. package/lib/test/client.reconnectFarm.spec.js +11 -8
  385. package/lib/test/client.reconnectFarm.spec.js.map +1 -1
  386. package/lib/test/client.replay.spec.js +8 -7
  387. package/lib/test/client.replay.spec.js.map +1 -1
  388. package/lib/test/client.rollback.spec.js +14 -11
  389. package/lib/test/client.rollback.spec.js.map +1 -1
  390. package/lib/test/client.rollbackFarm.spec.js +3 -1
  391. package/lib/test/client.rollbackFarm.spec.js.map +1 -1
  392. package/lib/test/client.searchForMarker.spec.js +29 -19
  393. package/lib/test/client.searchForMarker.spec.js.map +1 -1
  394. package/lib/test/client.walkSegments.spec.js +1 -1
  395. package/lib/test/client.walkSegments.spec.js.map +1 -1
  396. package/lib/test/collections.list.spec.js +1 -1
  397. package/lib/test/collections.list.spec.js.map +1 -1
  398. package/lib/test/createInsertOnlyAttributionPolicy.spec.js +1 -1
  399. package/lib/test/createInsertOnlyAttributionPolicy.spec.js.map +1 -1
  400. package/lib/test/dirname.cjs +1 -0
  401. package/lib/test/dirname.cjs.map +1 -1
  402. package/lib/test/dirname.d.cts.map +1 -1
  403. package/lib/test/mergeTree.annotate.deltaCallback.spec.js +1 -1
  404. package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  405. package/lib/test/mergeTree.annotate.spec.js +1 -1
  406. package/lib/test/mergeTree.annotate.spec.js.map +1 -1
  407. package/lib/test/mergeTree.insert.deltaCallback.spec.js +1 -1
  408. package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  409. package/lib/test/mergeTree.insertingWalk.spec.js +8 -8
  410. package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
  411. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +1 -1
  412. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  413. package/lib/test/mergeTree.markRangeRemoved.spec.js +1 -1
  414. package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  415. package/lib/test/mergeTree.walk.spec.js +1 -1
  416. package/lib/test/mergeTree.walk.spec.js.map +1 -1
  417. package/lib/test/mergeTree.zamboni.spec.js +1 -1
  418. package/lib/test/mergeTree.zamboni.spec.js.map +1 -1
  419. package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
  420. package/lib/test/mergeTreeOperationRunner.js +27 -15
  421. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  422. package/lib/test/mergeTreeOperationRunner.spec.js +5 -1
  423. package/lib/test/mergeTreeOperationRunner.spec.js.map +1 -1
  424. package/lib/test/obliterate.concurrent.spec.js +4 -4
  425. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  426. package/lib/test/obliterate.deltaCallback.spec.js +2 -3
  427. package/lib/test/obliterate.deltaCallback.spec.js.map +1 -1
  428. package/lib/test/obliterate.partialLength.spec.js +1 -1
  429. package/lib/test/obliterate.partialLength.spec.js.map +1 -1
  430. package/lib/test/obliterate.reconnect.spec.js +1 -1
  431. package/lib/test/obliterate.reconnect.spec.js.map +1 -1
  432. package/lib/test/obliterate.spec.js +1 -1
  433. package/lib/test/obliterate.spec.js.map +1 -1
  434. package/lib/test/ordinal.spec.js +7 -1
  435. package/lib/test/ordinal.spec.js.map +1 -1
  436. package/lib/test/partialLength.spec.js.map +1 -1
  437. package/lib/test/properties.spec.js +1 -1
  438. package/lib/test/properties.spec.js.map +1 -1
  439. package/lib/test/reconnectHelper.d.ts +4 -4
  440. package/lib/test/reconnectHelper.d.ts.map +1 -1
  441. package/lib/test/reconnectHelper.js +22 -14
  442. package/lib/test/reconnectHelper.js.map +1 -1
  443. package/lib/test/resetPendingSegmentsToOp.spec.js +8 -2
  444. package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  445. package/lib/test/revertibleFarm.spec.js +8 -7
  446. package/lib/test/revertibleFarm.spec.js.map +1 -1
  447. package/lib/test/revertibles.spec.d.ts.map +1 -1
  448. package/lib/test/revertibles.spec.js +93 -54
  449. package/lib/test/revertibles.spec.js.map +1 -1
  450. package/lib/test/segmentGroupCollection.spec.js +1 -1
  451. package/lib/test/segmentGroupCollection.spec.js.map +1 -1
  452. package/lib/test/snapshot.spec.js +1 -1
  453. package/lib/test/snapshot.spec.js.map +1 -1
  454. package/lib/test/snapshot.utils.d.ts.map +1 -1
  455. package/lib/test/snapshot.utils.js +1 -1
  456. package/lib/test/snapshot.utils.js.map +1 -1
  457. package/lib/test/snapshotlegacy.spec.js +10 -5
  458. package/lib/test/snapshotlegacy.spec.js.map +1 -1
  459. package/lib/test/sortedSegmentSet.spec.js +6 -2
  460. package/lib/test/sortedSegmentSet.spec.js.map +1 -1
  461. package/lib/test/testClient.d.ts +6 -5
  462. package/lib/test/testClient.d.ts.map +1 -1
  463. package/lib/test/testClient.js +25 -27
  464. package/lib/test/testClient.js.map +1 -1
  465. package/lib/test/testClientLogger.d.ts.map +1 -1
  466. package/lib/test/testClientLogger.js +37 -36
  467. package/lib/test/testClientLogger.js.map +1 -1
  468. package/lib/test/testSerializer.d.ts +5 -5
  469. package/lib/test/testSerializer.d.ts.map +1 -1
  470. package/lib/test/testSerializer.js +0 -1
  471. package/lib/test/testSerializer.js.map +1 -1
  472. package/lib/test/testServer.d.ts.map +1 -1
  473. package/lib/test/testServer.js.map +1 -1
  474. package/lib/test/testUtils.d.ts +1 -1
  475. package/lib/test/testUtils.d.ts.map +1 -1
  476. package/lib/test/testUtils.js +6 -8
  477. package/lib/test/testUtils.js.map +1 -1
  478. package/lib/test/text.d.ts.map +1 -1
  479. package/lib/test/text.js +1 -1
  480. package/lib/test/text.js.map +1 -1
  481. package/lib/test/tracking.spec.js +9 -5
  482. package/lib/test/tracking.spec.js.map +1 -1
  483. package/lib/test/wordUnitTests.spec.d.ts.map +1 -1
  484. package/lib/test/wordUnitTests.spec.js +9 -9
  485. package/lib/test/wordUnitTests.spec.js.map +1 -1
  486. package/lib/textSegment.d.ts +1 -1
  487. package/lib/textSegment.d.ts.map +1 -1
  488. package/lib/textSegment.js +3 -3
  489. package/lib/textSegment.js.map +1 -1
  490. package/lib/zamboni.d.ts.map +1 -1
  491. package/lib/zamboni.js +7 -2
  492. package/lib/zamboni.js.map +1 -1
  493. package/package.json +29 -27
  494. package/src/MergeTreeTextHelper.ts +2 -2
  495. package/src/attributionCollection.ts +71 -28
  496. package/src/attributionPolicy.ts +14 -9
  497. package/src/client.ts +120 -71
  498. package/src/collections/list.ts +9 -6
  499. package/src/collections/rbTree.ts +62 -71
  500. package/src/endOfTreeSegment.ts +21 -10
  501. package/src/localReference.ts +61 -43
  502. package/src/mergeTree.ts +229 -178
  503. package/src/mergeTreeNodeWalk.ts +2 -1
  504. package/src/mergeTreeNodes.ts +59 -46
  505. package/src/mergeTreeTracking.ts +3 -3
  506. package/src/opBuilder.ts +6 -1
  507. package/src/ops.ts +5 -0
  508. package/src/ordinal.ts +8 -1
  509. package/src/partialLengths.ts +143 -87
  510. package/src/perspective.ts +10 -7
  511. package/src/properties.ts +36 -18
  512. package/src/referencePositions.ts +7 -0
  513. package/src/revertibles.ts +71 -41
  514. package/src/segmentGroupCollection.ts +8 -6
  515. package/src/segmentPropertiesManager.ts +28 -24
  516. package/src/snapshotChunks.ts +12 -7
  517. package/src/snapshotLoader.ts +20 -17
  518. package/src/snapshotV1.ts +36 -18
  519. package/src/snapshotlegacy.ts +7 -5
  520. package/src/sortedSegmentSet.ts +9 -3
  521. package/src/sortedSet.ts +7 -3
  522. package/src/textSegment.ts +9 -9
  523. package/src/zamboni.ts +14 -10
  524. package/tsconfig.json +0 -1
package/src/mergeTree.ts CHANGED
@@ -77,7 +77,6 @@ import {
77
77
  } from "./ops.js";
78
78
  import { PartialSequenceLengths } from "./partialLengths.js";
79
79
  import { PerspectiveImpl, isSegmentPresent } from "./perspective.js";
80
- // eslint-disable-next-line import/no-deprecated
81
80
  import { PropertySet, createMap, extend, extendIfUndefined } from "./properties.js";
82
81
  import {
83
82
  DetachedReferencePosition,
@@ -98,7 +97,7 @@ function wasRemovedAfter(seg: ISegment, seq: number): boolean {
98
97
 
99
98
  function markSegmentMoved(seg: ISegment, moveInfo: IMoveInfo): void {
100
99
  seg.moveDst = moveInfo.moveDst;
101
- seg.movedClientIds = moveInfo.movedClientIds.slice();
100
+ seg.movedClientIds = [...moveInfo.movedClientIds];
102
101
  seg.movedSeqs = [moveInfo.movedSeq];
103
102
  seg.movedSeq = moveInfo.movedSeq;
104
103
  seg.localMovedSeq = moveInfo.localMovedSeq;
@@ -271,18 +270,19 @@ export function findRootMergeBlock(
271
270
  maybeRoot = maybeRoot.parent;
272
271
  }
273
272
 
274
- return maybeRoot?.mergeTree !== undefined ? maybeRoot : undefined;
273
+ return maybeRoot?.mergeTree === undefined ? undefined : maybeRoot;
275
274
  }
276
275
 
277
276
  /**
277
+ * Find the segment to which a reference will slide if it needs to slide, or undefined if there
278
+ * is no valid segment (i.e. the tree is empty).
279
+ *
278
280
  * @param segment - The segment to slide from.
279
281
  * @param cache - Optional cache mapping segments to their sliding destinations.
280
282
  * Excursions will be avoided for segments in the cache, and the cache will be populated with
281
283
  * entries for all segments visited during excursion.
282
284
  * This can reduce the number of times the tree needs to be scanned if a range containing many
283
285
  * SlideOnRemove references is removed.
284
- * @returns The segment a SlideOnRemove reference should slide to, or undefined if there is no
285
- * valid segment (i.e. the tree is empty).
286
286
  * @internal
287
287
  */
288
288
  function getSlideToSegment(
@@ -305,7 +305,7 @@ function getSlideToSegment(
305
305
  }
306
306
  const result: { seg?: ISegment } = {};
307
307
  cache?.set(segment, result);
308
- const goFurtherToFindSlideToSegment = (seg: ISegment) => {
308
+ const goFurtherToFindSlideToSegment = (seg: ISegment): boolean => {
309
309
  if (seg.seq !== UnassignedSequenceNumber && !isRemovedAndAckedOrMovedAndAcked(seg)) {
310
310
  result.seg = seg;
311
311
  return false;
@@ -366,7 +366,10 @@ export function getSlideToSegoff(
366
366
  segoff: { segment: ISegment | undefined; offset: number | undefined },
367
367
  slidingPreference: SlidingPreference = SlidingPreference.FORWARD,
368
368
  useNewSlidingBehavior: boolean = false,
369
- ) {
369
+ ): {
370
+ segment: ISegment | undefined;
371
+ offset: number | undefined;
372
+ } {
370
373
  if (segoff.segment === undefined) {
371
374
  return segoff;
372
375
  }
@@ -387,6 +390,11 @@ export function getSlideToSegoff(
387
390
  };
388
391
  }
389
392
 
393
+ const forwardPred = (ref: LocalReferencePosition): boolean =>
394
+ ref.slidingPreference !== SlidingPreference.BACKWARD;
395
+ const backwardPred = (ref: LocalReferencePosition): boolean =>
396
+ ref.slidingPreference === SlidingPreference.BACKWARD;
397
+
390
398
  /**
391
399
  * @internal
392
400
  */
@@ -465,12 +473,12 @@ export class MergeTree {
465
473
  return this._root;
466
474
  }
467
475
 
468
- public set root(value) {
476
+ public set root(value: IRootMergeBlock) {
469
477
  this._root = value;
470
478
  value.mergeTree = this;
471
479
  }
472
480
 
473
- public makeBlock(childCount: number) {
481
+ public makeBlock(childCount: number): MergeBlock {
474
482
  const block = new MergeBlock(childCount);
475
483
  block.ordinal = "";
476
484
  return block;
@@ -513,7 +521,22 @@ export class MergeTree {
513
521
  );
514
522
  assert(segment.seq !== undefined, 0x399 /* segment with no seq in mergeTree */);
515
523
  const { seq, removedSeq, localRemovedSeq, movedSeq, localMovedSeq } = segment;
516
- if (seq !== UnassignedSequenceNumber) {
524
+ if (seq === UnassignedSequenceNumber) {
525
+ assert(
526
+ segment.localSeq !== undefined,
527
+ 0x39a /* unacked segment with undefined localSeq */,
528
+ );
529
+ // inserted locally, still un-acked
530
+ if (
531
+ segment.localSeq > localSeq ||
532
+ (localRemovedSeq !== undefined && localRemovedSeq <= localSeq) ||
533
+ (localMovedSeq !== undefined && localMovedSeq <= localSeq)
534
+ ) {
535
+ return 0;
536
+ }
537
+ const { cachedLength } = segment;
538
+ return cachedLength;
539
+ } else {
517
540
  // inserted remotely
518
541
  if (
519
542
  seq > refSeq ||
@@ -529,37 +552,23 @@ export class MergeTree {
529
552
  return 0;
530
553
  }
531
554
  return segment.cachedLength;
532
- } else {
533
- assert(
534
- segment.localSeq !== undefined,
535
- 0x39a /* unacked segment with undefined localSeq */,
536
- );
537
- // inserted locally, still un-acked
538
- if (
539
- segment.localSeq > localSeq ||
540
- (localRemovedSeq !== undefined && localRemovedSeq <= localSeq) ||
541
- (localMovedSeq !== undefined && localMovedSeq <= localSeq)
542
- ) {
543
- return 0;
544
- }
545
- return segment.cachedLength;
546
555
  }
547
556
  }
548
557
 
549
- public unlinkMarker(marker: Marker) {
558
+ public unlinkMarker(marker: Marker): void {
550
559
  const id = marker.getId();
551
560
  if (id) {
552
561
  this.idToMarker.delete(id);
553
562
  }
554
563
  }
555
564
 
556
- private addNode(block: MergeBlock, node: IMergeNode) {
565
+ private addNode(block: MergeBlock, node: IMergeNode): number {
557
566
  const index = block.childCount++;
558
567
  block.assignChild(node, index, false);
559
568
  return index;
560
569
  }
561
570
 
562
- public reloadFromSegments(segments: ISegment[]) {
571
+ public reloadFromSegments(segments: ISegment[]): void {
563
572
  // This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
564
573
  assert(
565
574
  !this.collabWindow.collaborating,
@@ -571,7 +580,7 @@ export class MergeTree {
571
580
  // Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
572
581
  const buildMergeBlock = (nodes: IMergeNode[]): IRootMergeBlock => {
573
582
  const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
574
- const blocks: MergeBlock[] = new Array(blockCount); // Pre-alloc array to collect nodes
583
+ const blocks: MergeBlock[] = Array.from({ length: blockCount }); // Pre-alloc array to collect nodes
575
584
 
576
585
  // For each block in this level of the B-Tree...
577
586
  for (
@@ -589,7 +598,8 @@ export class MergeTree {
589
598
  childIndex++, nodeIndex++ // Advance to next child & node
590
599
  ) {
591
600
  // Insert the next node into the current block
592
- this.addNode(block, nodes[nodeIndex]);
601
+ // TODO Non null asserting, why is this not null?
602
+ this.addNode(block, nodes[nodeIndex]!);
593
603
  }
594
604
 
595
605
  // Calculate this block's info. Previously this was inlined into the above loop as a micro-optimization,
@@ -599,7 +609,8 @@ export class MergeTree {
599
609
  }
600
610
 
601
611
  return blocks.length === 1 // If there is only one block at this layer...
602
- ? blocks[0] // ...then we're done. Return the root.
612
+ ? // Non null asserting here because of the length check above
613
+ blocks[0]! // ...then we're done. Return the root.
603
614
  : buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
604
615
  };
605
616
  if (segments.length > 0) {
@@ -611,7 +622,7 @@ export class MergeTree {
611
622
  }
612
623
 
613
624
  // For now assume min starts at zero
614
- public startCollaboration(localClientId: number, minSeq: number, currentSeq: number) {
625
+ public startCollaboration(localClientId: number, minSeq: number, currentSeq: number): void {
615
626
  this.collabWindow.clientId = localClientId;
616
627
  this.collabWindow.minSeq = minSeq;
617
628
  this.collabWindow.collaborating = true;
@@ -619,7 +630,7 @@ export class MergeTree {
619
630
  this.nodeUpdateLengthNewStructure(this.root, true);
620
631
  }
621
632
 
622
- private addToLRUSet(leaf: ISegmentLeaf, seq: number) {
633
+ private addToLRUSet(leaf: ISegmentLeaf, seq: number): void {
623
634
  // If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
624
635
  // add the segment and mark the mark the node now.
625
636
 
@@ -638,7 +649,7 @@ export class MergeTree {
638
649
  /**
639
650
  * Returns the current length of the MergeTree for the local client.
640
651
  */
641
- public get length() {
652
+ public get length(): number | undefined {
642
653
  return this.root.cachedLength;
643
654
  }
644
655
 
@@ -658,7 +669,8 @@ export class MergeTree {
658
669
  while (parent) {
659
670
  const children = parent.children;
660
671
  for (let childIndex = 0; childIndex < parent.childCount; childIndex++) {
661
- const child = children[childIndex];
672
+ // TODO Non null asserting, why is this not null?
673
+ const child = children[childIndex]!;
662
674
  if ((!!prevParent && child === prevParent) || child === node) {
663
675
  break;
664
676
  }
@@ -675,7 +687,10 @@ export class MergeTree {
675
687
  refSeq: number,
676
688
  clientId: number,
677
689
  localSeq?: number,
678
- ) {
690
+ ): {
691
+ segment: T | undefined;
692
+ offset: number | undefined;
693
+ } {
679
694
  assert(
680
695
  localSeq === undefined || clientId === this.collabWindow.clientId,
681
696
  0x39b /* localSeq provided for non-local client */,
@@ -689,7 +704,7 @@ export class MergeTree {
689
704
  _refSeq: number,
690
705
  _clientId: number,
691
706
  start: number,
692
- ) => {
707
+ ): boolean => {
693
708
  segment = leafSeg as T;
694
709
  offset = start;
695
710
  return false;
@@ -718,7 +733,7 @@ export class MergeTree {
718
733
  *
719
734
  * @param segments - An array of (not necessarily contiguous) segments with increasing ordinals.
720
735
  */
721
- private slideAckedRemovedSegmentReferences(segments: ISegment[]) {
736
+ private slideAckedRemovedSegmentReferences(segments: ISegment[]): void {
722
737
  // References are slid in groups to preserve their order.
723
738
  let currentForwardSlideGroup: LocalReferenceCollection[] = [];
724
739
  let currentBackwardSlideGroup: LocalReferenceCollection[] = [];
@@ -726,14 +741,10 @@ export class MergeTree {
726
741
  let currentForwardMaybeEndpoint: "start" | "end" | undefined;
727
742
  let currentForwardSlideDestination: ISegment | undefined;
728
743
  let currentForwardSlideIsForward: boolean | undefined;
729
- const forwardPred = (ref: LocalReferencePosition) =>
730
- ref.slidingPreference !== SlidingPreference.BACKWARD;
731
744
 
732
745
  let currentBackwardMaybeEndpoint: "start" | "end" | undefined;
733
746
  let currentBackwardSlideDestination: ISegment | undefined;
734
747
  let currentBackwardSlideIsForward: boolean | undefined;
735
- const backwardPred = (ref: LocalReferencePosition) =>
736
- ref.slidingPreference === SlidingPreference.BACKWARD;
737
748
 
738
749
  const slideGroup = (
739
750
  currentSlideDestination: ISegmentLeaf | undefined,
@@ -741,7 +752,7 @@ export class MergeTree {
741
752
  currentSlideGroup: LocalReferenceCollection[],
742
753
  pred: (ref: LocalReferencePosition) => boolean,
743
754
  maybeEndpoint: "start" | "end" | undefined,
744
- ) => {
755
+ ): void => {
745
756
  if (currentSlideIsForward === undefined) {
746
757
  return;
747
758
  }
@@ -770,14 +781,7 @@ export class MergeTree {
770
781
  }
771
782
  }
772
783
 
773
- if (currentSlideDestination !== undefined) {
774
- const localRefs = LocalReferenceCollection.setOrGet(currentSlideDestination);
775
- if (currentSlideIsForward) {
776
- localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
777
- } else {
778
- localRefs.addAfterTombstones(...nonEndpointRefsToAdd);
779
- }
780
- } else {
784
+ if (currentSlideDestination === undefined) {
781
785
  for (const collection of currentSlideGroup) {
782
786
  for (const ref of collection) {
783
787
  if (pred(ref) && !refTypeIncludesFlag(ref, ReferenceType.StayOnRemove)) {
@@ -787,6 +791,13 @@ export class MergeTree {
787
791
  }
788
792
  }
789
793
  }
794
+ } else {
795
+ const localRefs = LocalReferenceCollection.setOrGet(currentSlideDestination);
796
+ if (currentSlideIsForward) {
797
+ localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
798
+ } else {
799
+ localRefs.addAfterTombstones(...nonEndpointRefsToAdd);
800
+ }
790
801
  }
791
802
  };
792
803
 
@@ -804,7 +815,7 @@ export class MergeTree {
804
815
  slideIsForward: boolean,
805
816
  maybeEndpoint: "start" | "end" | undefined,
806
817
  ) => void,
807
- ) => {
818
+ ): void => {
808
819
  // avoid sliding logic if this segment doesn't have any references
809
820
  // with the given sliding preference
810
821
  if (!segment.localRefs || !anyLocalReferencePosition(segment.localRefs, pred)) {
@@ -916,7 +927,7 @@ export class MergeTree {
916
927
  *
917
928
  * Public only for use by internal tests
918
929
  */
919
- public computeLocalPartials(refSeq: number) {
930
+ public computeLocalPartials(refSeq: number): void {
920
931
  if (this.localPartialsComputed) {
921
932
  return;
922
933
  }
@@ -966,13 +977,7 @@ export class MergeTree {
966
977
  }
967
978
  } else {
968
979
  // Sequence number within window
969
- if (!node.isLeaf()) {
970
- const partialLen = node.partialLengths!.getPartialLength(refSeq, clientId);
971
-
972
- PartialSequenceLengths.options.verifyExpected?.(this, node, refSeq, clientId);
973
-
974
- return partialLen;
975
- } else {
980
+ if (node.isLeaf()) {
976
981
  const segment = node;
977
982
  const removalInfo = toRemovalInfo(segment);
978
983
  const moveInfo = toMoveInfo(segment);
@@ -1004,11 +1009,17 @@ export class MergeTree {
1004
1009
  return seqLTE(node.seq ?? 0, refSeq) || segment.clientId === clientId
1005
1010
  ? segment.cachedLength
1006
1011
  : 0;
1012
+ } else {
1013
+ const partialLen = node.partialLengths!.getPartialLength(refSeq, clientId);
1014
+
1015
+ PartialSequenceLengths.options.verifyExpected?.(this, node, refSeq, clientId);
1016
+
1017
+ return partialLen;
1007
1018
  }
1008
1019
  }
1009
1020
  }
1010
1021
 
1011
- public setMinSeq(minSeq: number) {
1022
+ public setMinSeq(minSeq: number): void {
1012
1023
  assert(
1013
1024
  minSeq <= this.collabWindow.currentSeq,
1014
1025
  0x04e /* "Trying to set minSeq above currentSeq of collab window!" */,
@@ -1038,7 +1049,6 @@ export class MergeTree {
1038
1049
  * Defaults to including all edits which have been applied.
1039
1050
  * @param clientId - The ID of the client from whose perspective to resolve this reference. Defaults to the current client.
1040
1051
  * @param localSeq - The local sequence number to consider. Defaults to including all local edits.
1041
- * @returns the count of elements before the given reference position in the given perspective.
1042
1052
  */
1043
1053
  public referencePositionToLocalPosition(
1044
1054
  refPos: ReferencePosition,
@@ -1129,7 +1139,7 @@ export class MergeTree {
1129
1139
  foundMarker = marker;
1130
1140
  }
1131
1141
  }
1132
- return foundMarker !== undefined ? NodeAction.Exit : NodeAction.Skip;
1142
+ return foundMarker === undefined ? NodeAction.Skip : NodeAction.Exit;
1133
1143
  },
1134
1144
  undefined,
1135
1145
  undefined,
@@ -1139,7 +1149,7 @@ export class MergeTree {
1139
1149
  return foundMarker;
1140
1150
  }
1141
1151
 
1142
- private updateRoot(splitNode: MergeBlock | undefined) {
1152
+ private updateRoot(splitNode: MergeBlock | undefined): void {
1143
1153
  if (splitNode !== undefined) {
1144
1154
  const newRoot = this.makeBlock(2);
1145
1155
  newRoot.assignChild(this.root, 0, false);
@@ -1154,7 +1164,7 @@ export class MergeTree {
1154
1164
  * Assign sequence number to existing segment; update partial lengths to reflect the change
1155
1165
  * @param seq - sequence number given by server to pending segment
1156
1166
  */
1157
- public ackPendingSegment(opArgs: IMergeTreeDeltaOpArgs) {
1167
+ public ackPendingSegment(opArgs: IMergeTreeDeltaOpArgs): void {
1158
1168
  const seq = opArgs.sequencedMessage!.sequenceNumber;
1159
1169
  const pendingSegmentGroup = this.pendingSegments.shift()?.data;
1160
1170
  const nodesToUpdate: MergeBlock[] = [];
@@ -1170,6 +1180,8 @@ export class MergeTree {
1170
1180
  const locallyMovedSegments = this.locallyMovedSegments.get(localMovedSeq);
1171
1181
 
1172
1182
  if (locallyMovedSegments) {
1183
+ // Disabling because a for of loop causes the type of segment to be ISegment, which does not have parent information stored
1184
+ // eslint-disable-next-line unicorn/no-array-for-each
1173
1185
  locallyMovedSegments.segments.forEach((segment: ISegmentLeaf) => {
1174
1186
  segment.localMovedSeq = undefined;
1175
1187
 
@@ -1241,7 +1253,8 @@ export class MergeTree {
1241
1253
  segmentGroup?: SegmentGroup,
1242
1254
  localSeq?: number,
1243
1255
  previousProps?: PropertySet,
1244
- ) {
1256
+ // eslint-disable-next-line import/no-deprecated
1257
+ ): SegmentGroup {
1245
1258
  let _segmentGroup = segmentGroup;
1246
1259
  if (_segmentGroup === undefined) {
1247
1260
  _segmentGroup = {
@@ -1290,7 +1303,7 @@ export class MergeTree {
1290
1303
  relativePos: IRelativePosition,
1291
1304
  refseq = this.collabWindow.currentSeq,
1292
1305
  clientId = this.collabWindow.clientId,
1293
- ) {
1306
+ ): number {
1294
1307
  let pos = -1;
1295
1308
  let marker: Marker | undefined;
1296
1309
  if (relativePos.id) {
@@ -1298,14 +1311,14 @@ export class MergeTree {
1298
1311
  }
1299
1312
  if (marker) {
1300
1313
  pos = this.getPosition(marker, refseq, clientId);
1301
- if (!relativePos.before) {
1302
- pos += marker.cachedLength;
1314
+ if (relativePos.before) {
1303
1315
  if (relativePos.offset !== undefined) {
1304
- pos += relativePos.offset;
1316
+ pos -= relativePos.offset;
1305
1317
  }
1306
1318
  } else {
1319
+ pos += marker.cachedLength;
1307
1320
  if (relativePos.offset !== undefined) {
1308
- pos -= relativePos.offset;
1321
+ pos += relativePos.offset;
1309
1322
  }
1310
1323
  }
1311
1324
  }
@@ -1319,7 +1332,7 @@ export class MergeTree {
1319
1332
  clientId: number,
1320
1333
  seq: number,
1321
1334
  opArgs: IMergeTreeDeltaOpArgs | undefined,
1322
- ) {
1335
+ ): void {
1323
1336
  this.ensureIntervalBoundary(pos, refSeq, clientId);
1324
1337
 
1325
1338
  const localSeq =
@@ -1398,8 +1411,10 @@ export class MergeTree {
1398
1411
  seq: number,
1399
1412
  localSeq: number | undefined,
1400
1413
  newSegments: T[],
1401
- ) {
1402
- const continueFrom = (node: MergeBlock) => {
1414
+ ): void {
1415
+ // Keeping this function within the scope of blockInsert for readability.
1416
+ // eslint-disable-next-line unicorn/consistent-function-scoping
1417
+ const continueFrom = (node: MergeBlock): boolean => {
1403
1418
  let siblingExists = false;
1404
1419
  forwardExcursion(node, () => {
1405
1420
  siblingExists = true;
@@ -1407,10 +1422,9 @@ export class MergeTree {
1407
1422
  });
1408
1423
  return siblingExists;
1409
1424
  };
1410
-
1411
1425
  // eslint-disable-next-line import/no-deprecated
1412
1426
  let segmentGroup: SegmentGroup;
1413
- const saveIfLocal = (locSegment: ISegment) => {
1427
+ const saveIfLocal = (locSegment: ISegment): void => {
1414
1428
  // Save segment so we can assign sequence number when acked by server
1415
1429
  if (this.collabWindow.collaborating) {
1416
1430
  if (
@@ -1430,7 +1444,13 @@ export class MergeTree {
1430
1444
  }
1431
1445
  }
1432
1446
  };
1433
- const onLeaf = (segment: ISegment | undefined, _pos: number, context: InsertContext) => {
1447
+ const onLeaf = (
1448
+ segment: ISegment | undefined,
1449
+ _pos: number,
1450
+ context: InsertContext,
1451
+ // Keeping this function within the scope of blockInsert for readability.
1452
+ // eslint-disable-next-line unicorn/consistent-function-scoping
1453
+ ): ISegmentChanges => {
1434
1454
  const segmentChanges: ISegmentChanges = {};
1435
1455
  if (segment) {
1436
1456
  // Insert before segment
@@ -1464,7 +1484,7 @@ export class MergeTree {
1464
1484
 
1465
1485
  if (newSegment.parent === undefined) {
1466
1486
  // Indicates an attempt to insert past the end of the merge-tree's content.
1467
- const errorConstructor = localSeq !== undefined ? UsageError : DataProcessingError;
1487
+ const errorConstructor = localSeq === undefined ? DataProcessingError : UsageError;
1468
1488
  throw new errorConstructor("MergeTree insert failed", {
1469
1489
  currentSeq: this.collabWindow.currentSeq,
1470
1490
  minSeq: this.collabWindow.minSeq,
@@ -1495,7 +1515,7 @@ export class MergeTree {
1495
1515
  let _movedSeq: number | undefined;
1496
1516
  let movedClientIds: number[] | undefined;
1497
1517
 
1498
- const findLeftMovedSegment = (seg: ISegment) => {
1518
+ const findLeftMovedSegment = (seg: ISegment): boolean => {
1499
1519
  const movedSeqs = seg.movedSeqs?.filter((movedSeq) => movedSeq >= refSeq) ?? [];
1500
1520
  const localMovedSeqs = seg.localMovedSeq ? [seg.localMovedSeq] : [];
1501
1521
  for (const movedSeq of movedSeqs) {
@@ -1518,7 +1538,7 @@ export class MergeTree {
1518
1538
  return moveUpperBound >= smallestSeqMoveOp;
1519
1539
  };
1520
1540
 
1521
- const findRightMovedSegment = (seg: ISegment) => {
1541
+ const findRightMovedSegment = (seg: ISegment): boolean => {
1522
1542
  const movedSeqs = seg.movedSeqs?.filter((movedSeq) => movedSeq >= refSeq) ?? [];
1523
1543
  const localMovedSeqs = seg.localMovedSeq ? [seg.localMovedSeq] : [];
1524
1544
 
@@ -1616,7 +1636,7 @@ export class MergeTree {
1616
1636
  return { next };
1617
1637
  };
1618
1638
 
1619
- private ensureIntervalBoundary(pos: number, refSeq: number, clientId: number) {
1639
+ private ensureIntervalBoundary(pos: number, refSeq: number, clientId: number): void {
1620
1640
  const splitNode = this.insertingWalk(
1621
1641
  this.root,
1622
1642
  pos,
@@ -1629,7 +1649,7 @@ export class MergeTree {
1629
1649
  }
1630
1650
 
1631
1651
  // Assume called only when pos == len
1632
- private breakTie(pos: number, node: IMergeNode, seq: number) {
1652
+ private breakTie(pos: number, node: IMergeNode, seq: number): boolean {
1633
1653
  if (node.isLeaf()) {
1634
1654
  if (pos !== 0) {
1635
1655
  return false;
@@ -1670,7 +1690,7 @@ export class MergeTree {
1670
1690
  seq: number,
1671
1691
  context: InsertContext,
1672
1692
  isLastChildBlock: boolean = true,
1673
- ) {
1693
+ ): MergeBlock | undefined {
1674
1694
  let _pos = pos;
1675
1695
  const children = block.children;
1676
1696
  let childIndex: number;
@@ -1678,7 +1698,8 @@ export class MergeTree {
1678
1698
  let newNode: IMergeNode | undefined;
1679
1699
  let fromSplit: MergeBlock | undefined;
1680
1700
  for (childIndex = 0; childIndex < block.childCount; childIndex++) {
1681
- child = children[childIndex];
1701
+ // TODO Non null asserting, why is this not null?
1702
+ child = children[childIndex]!;
1682
1703
  // ensure we walk down the far edge of the tree, even if all sub-tree is eligible for zamboni
1683
1704
  const isLastNonLeafBlock =
1684
1705
  isLastChildBlock && !child.isLeaf() && childIndex === block.childCount - 1;
@@ -1695,7 +1716,21 @@ export class MergeTree {
1695
1716
 
1696
1717
  if (_pos < len || (_pos === len && this.breakTie(_pos, child, seq))) {
1697
1718
  // Found entry containing pos
1698
- if (!child.isLeaf()) {
1719
+ if (child.isLeaf()) {
1720
+ const segment = child;
1721
+ const segmentChanges = context.leaf(segment, _pos, context);
1722
+ if (segmentChanges.replaceCurrent) {
1723
+ block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
1724
+ segmentChanges.replaceCurrent.ordinal = child.ordinal;
1725
+ }
1726
+ if (segmentChanges.next) {
1727
+ newNode = segmentChanges.next;
1728
+ childIndex++; // Insert after
1729
+ } else {
1730
+ // No change
1731
+ return undefined;
1732
+ }
1733
+ } else {
1699
1734
  const childBlock = child;
1700
1735
  // Internal node
1701
1736
  const splitNode = this.insertingWalk(
@@ -1718,41 +1753,27 @@ export class MergeTree {
1718
1753
  fromSplit = splitNode;
1719
1754
  childIndex++; // Insert after
1720
1755
  }
1721
- } else {
1722
- const segment = child;
1723
- const segmentChanges = context.leaf(segment, _pos, context);
1724
- if (segmentChanges.replaceCurrent) {
1725
- block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
1726
- segmentChanges.replaceCurrent.ordinal = child.ordinal;
1727
- }
1728
- if (segmentChanges.next) {
1729
- newNode = segmentChanges.next;
1730
- childIndex++; // Insert after
1731
- } else {
1732
- // No change
1733
- return undefined;
1734
- }
1735
1756
  }
1736
1757
  break;
1737
1758
  } else {
1738
1759
  _pos -= len;
1739
1760
  }
1740
1761
  }
1741
- if (!newNode) {
1742
- if (_pos === 0) {
1743
- if (context.continuePredicate?.(block)) {
1744
- return MergeTree.theUnfinishedNode;
1745
- } else {
1746
- const segmentChanges = context.leaf(undefined, _pos, context);
1747
- newNode = segmentChanges.next;
1748
- // Assert segmentChanges.replaceCurrent === undefined
1749
- }
1762
+ if (!newNode && _pos === 0) {
1763
+ if (context.continuePredicate?.(block)) {
1764
+ return MergeTree.theUnfinishedNode;
1765
+ } else {
1766
+ const segmentChanges = context.leaf(undefined, _pos, context);
1767
+ newNode = segmentChanges.next;
1768
+ // Assert segmentChanges.replaceCurrent === undefined
1750
1769
  }
1751
1770
  }
1752
1771
  if (newNode) {
1753
1772
  for (let i = block.childCount; i > childIndex; i--) {
1754
- block.children[i] = block.children[i - 1];
1755
- block.children[i].index = i;
1773
+ // TODO Non null asserting, why is this not null?
1774
+ block.children[i] = block.children[i - 1]!;
1775
+ // TODO Non null asserting, why is this not null?
1776
+ block.children[i]!.index = i;
1756
1777
  }
1757
1778
  block.assignChild(newNode, childIndex, false);
1758
1779
  block.childCount++;
@@ -1782,14 +1803,15 @@ export class MergeTree {
1782
1803
  }
1783
1804
  }
1784
1805
 
1785
- private split(node: MergeBlock) {
1806
+ private split(node: MergeBlock): MergeBlock {
1786
1807
  const halfCount = MaxNodesInBlock / 2;
1787
1808
  const newNode = this.makeBlock(halfCount);
1788
1809
  node.childCount = halfCount;
1789
1810
  // Update ordinals to reflect lowered child count
1790
1811
  this.nodeUpdateOrdinals(node);
1791
1812
  for (let i = 0; i < halfCount; i++) {
1792
- newNode.assignChild(node.children[halfCount + i], i, false);
1813
+ // TODO Non null asserting, why is this not null?
1814
+ newNode.assignChild(node.children[halfCount + i]!, i, false);
1793
1815
  node.children[halfCount + i] = undefined!;
1794
1816
  }
1795
1817
  this.nodeUpdateLengthNewStructure(node);
@@ -1797,9 +1819,10 @@ export class MergeTree {
1797
1819
  return newNode;
1798
1820
  }
1799
1821
 
1800
- public nodeUpdateOrdinals(block: MergeBlock) {
1822
+ public nodeUpdateOrdinals(block: MergeBlock): void {
1801
1823
  for (let i = 0; i < block.childCount; i++) {
1802
- const child = block.children[i];
1824
+ // TODO Non null asserting, why is this not null?
1825
+ const child = block.children[i]!;
1803
1826
  block.setOrdinal(child, i);
1804
1827
  if (!child.isLeaf()) {
1805
1828
  this.nodeUpdateOrdinals(child);
@@ -1827,7 +1850,7 @@ export class MergeTree {
1827
1850
  seq: number,
1828
1851
  opArgs: IMergeTreeDeltaOpArgs,
1829
1852
  rollback: PropertiesRollback = PropertiesRollback.None,
1830
- ) {
1853
+ ): void {
1831
1854
  this.ensureIntervalBoundary(start, refSeq, clientId);
1832
1855
  this.ensureIntervalBoundary(end, refSeq, clientId);
1833
1856
  const deltaSegments: IMergeTreeSegmentDelta[] = [];
@@ -1835,7 +1858,7 @@ export class MergeTree {
1835
1858
  seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
1836
1859
  // eslint-disable-next-line import/no-deprecated
1837
1860
  let segmentGroup: SegmentGroup | undefined;
1838
- const annotateSegment = (segment: ISegment) => {
1861
+ const annotateSegment = (segment: ISegment): boolean => {
1839
1862
  assert(
1840
1863
  !Marker.is(segment) ||
1841
1864
  !(reservedMarkerIdKey in props) ||
@@ -1877,10 +1900,12 @@ export class MergeTree {
1877
1900
  deltaSegments,
1878
1901
  });
1879
1902
  }
1880
- if (this.collabWindow.collaborating && seq !== UnassignedSequenceNumber) {
1881
- if (MergeTree.options.zamboniSegments) {
1882
- zamboniSegments(this);
1883
- }
1903
+ if (
1904
+ this.collabWindow.collaborating &&
1905
+ seq !== UnassignedSequenceNumber &&
1906
+ MergeTree.options.zamboniSegments
1907
+ ) {
1908
+ zamboniSegments(this);
1884
1909
  }
1885
1910
  }
1886
1911
 
@@ -1912,7 +1937,12 @@ export class MergeTree {
1912
1937
  }
1913
1938
  // eslint-disable-next-line import/no-deprecated
1914
1939
  let segmentGroup: SegmentGroup;
1915
- const markMoved = (segment: ISegment, pos: number, _start: number, _end: number) => {
1940
+ const markMoved = (
1941
+ segment: ISegment,
1942
+ pos: number,
1943
+ _start: number,
1944
+ _end: number,
1945
+ ): boolean => {
1916
1946
  const existingMoveInfo = toMoveInfo(segment);
1917
1947
 
1918
1948
  if (
@@ -1924,7 +1954,16 @@ export class MergeTree {
1924
1954
  segment.wasMovedOnInsert = true;
1925
1955
  }
1926
1956
 
1927
- if (existingMoveInfo !== undefined) {
1957
+ if (existingMoveInfo === undefined) {
1958
+ segment.movedClientIds = [clientId];
1959
+ segment.movedSeq = seq;
1960
+ segment.localMovedSeq = localSeq;
1961
+ segment.movedSeqs = [seq];
1962
+
1963
+ if (!toRemovalInfo(segment)) {
1964
+ movedSegments.push({ segment });
1965
+ }
1966
+ } else {
1928
1967
  _overwrite = true;
1929
1968
  if (existingMoveInfo.movedSeq === UnassignedSequenceNumber) {
1930
1969
  // we moved this locally, but someone else moved it first
@@ -1943,15 +1982,6 @@ export class MergeTree {
1943
1982
  existingMoveInfo.movedClientIds.push(clientId);
1944
1983
  existingMoveInfo.movedSeqs.push(seq);
1945
1984
  }
1946
- } else {
1947
- segment.movedClientIds = [clientId];
1948
- segment.movedSeq = seq;
1949
- segment.localMovedSeq = localSeq;
1950
- segment.movedSeqs = [seq];
1951
-
1952
- if (!toRemovalInfo(segment)) {
1953
- movedSegments.push({ segment });
1954
- }
1955
1985
  }
1956
1986
 
1957
1987
  // Save segment so can assign moved sequence number when acked by server
@@ -1970,7 +2000,12 @@ export class MergeTree {
1970
2000
  return true;
1971
2001
  };
1972
2002
 
1973
- const afterMarkMoved = (node: MergeBlock, pos: number, _start: number, _end: number) => {
2003
+ const afterMarkMoved = (
2004
+ node: MergeBlock,
2005
+ pos: number,
2006
+ _start: number,
2007
+ _end: number,
2008
+ ): boolean => {
1974
2009
  if (_overwrite) {
1975
2010
  this.nodeUpdateLengthNewStructure(node);
1976
2011
  } else {
@@ -1988,7 +2023,7 @@ export class MergeTree {
1988
2023
  start,
1989
2024
  end,
1990
2025
  undefined,
1991
- seq !== UnassignedSequenceNumber ? seq : undefined,
2026
+ seq === UnassignedSequenceNumber ? undefined : seq,
1992
2027
  );
1993
2028
 
1994
2029
  this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
@@ -2011,10 +2046,12 @@ export class MergeTree {
2011
2046
  this.slideAckedRemovedSegmentReferences(movedSegments.map(({ segment }) => segment));
2012
2047
  }
2013
2048
 
2014
- if (this.collabWindow.collaborating && seq !== UnassignedSequenceNumber) {
2015
- if (MergeTree.options.zamboniSegments) {
2016
- zamboniSegments(this);
2017
- }
2049
+ if (
2050
+ this.collabWindow.collaborating &&
2051
+ seq !== UnassignedSequenceNumber &&
2052
+ MergeTree.options.zamboniSegments
2053
+ ) {
2054
+ zamboniSegments(this);
2018
2055
  }
2019
2056
  }
2020
2057
 
@@ -2036,10 +2073,23 @@ export class MergeTree {
2036
2073
  const localOverlapWithRefs: ISegment[] = [];
2037
2074
  const localSeq =
2038
2075
  seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
2039
- const markRemoved = (segment: ISegment, pos: number, _start: number, _end: number) => {
2076
+ const markRemoved = (
2077
+ segment: ISegment,
2078
+ pos: number,
2079
+ _start: number,
2080
+ _end: number,
2081
+ ): boolean => {
2040
2082
  const existingRemovalInfo = toRemovalInfo(segment);
2041
2083
 
2042
- if (existingRemovalInfo !== undefined) {
2084
+ if (existingRemovalInfo === undefined) {
2085
+ segment.removedClientIds = [clientId];
2086
+ segment.removedSeq = seq;
2087
+ segment.localRemovedSeq = localSeq;
2088
+
2089
+ if (!toMoveInfo(segment)) {
2090
+ removedSegments.push({ segment });
2091
+ }
2092
+ } else {
2043
2093
  _overwrite = true;
2044
2094
  if (existingRemovalInfo.removedSeq === UnassignedSequenceNumber) {
2045
2095
  // we removed this locally, but someone else removed it first
@@ -2056,14 +2106,6 @@ export class MergeTree {
2056
2106
  // Do not replace earlier sequence number for remove
2057
2107
  existingRemovalInfo.removedClientIds.push(clientId);
2058
2108
  }
2059
- } else {
2060
- segment.removedClientIds = [clientId];
2061
- segment.removedSeq = seq;
2062
- segment.localRemovedSeq = localSeq;
2063
-
2064
- if (!toMoveInfo(segment)) {
2065
- removedSegments.push({ segment });
2066
- }
2067
2109
  }
2068
2110
 
2069
2111
  // Save segment so we can assign removed sequence number when acked by server
@@ -2081,7 +2123,12 @@ export class MergeTree {
2081
2123
  }
2082
2124
  return true;
2083
2125
  };
2084
- const afterMarkRemoved = (node: MergeBlock, pos: number, _start: number, _end: number) => {
2126
+ const afterMarkRemoved = (
2127
+ node: MergeBlock,
2128
+ pos: number,
2129
+ _start: number,
2130
+ _end: number,
2131
+ ): boolean => {
2085
2132
  if (_overwrite) {
2086
2133
  this.nodeUpdateLengthNewStructure(node);
2087
2134
  } else {
@@ -2107,10 +2154,12 @@ export class MergeTree {
2107
2154
  this.slideAckedRemovedSegmentReferences(removedSegments.map(({ segment }) => segment));
2108
2155
  }
2109
2156
 
2110
- if (this.collabWindow.collaborating && seq !== UnassignedSequenceNumber) {
2111
- if (MergeTree.options.zamboniSegments) {
2112
- zamboniSegments(this);
2113
- }
2157
+ if (
2158
+ this.collabWindow.collaborating &&
2159
+ seq !== UnassignedSequenceNumber &&
2160
+ MergeTree.options.zamboniSegments
2161
+ ) {
2162
+ zamboniSegments(this);
2114
2163
  }
2115
2164
  }
2116
2165
 
@@ -2118,12 +2167,14 @@ export class MergeTree {
2118
2167
  * Revert an unacked local op
2119
2168
  */
2120
2169
  // eslint-disable-next-line import/no-deprecated
2121
- public rollback(op: IMergeTreeDeltaOp, localOpMetadata: SegmentGroup) {
2170
+ public rollback(op: IMergeTreeDeltaOp, localOpMetadata: SegmentGroup): void {
2122
2171
  if (op.type === MergeTreeDeltaType.REMOVE) {
2123
2172
  const pendingSegmentGroup = this.pendingSegments.pop?.()?.data;
2124
2173
  if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
2125
2174
  throw new Error("Rollback op doesn't match last edit");
2126
2175
  }
2176
+ // Disabling because a for of loop causes the type of segment to be ISegment, which does not have parent information stored
2177
+ // eslint-disable-next-line unicorn/no-array-for-each
2127
2178
  pendingSegmentGroup.segments.forEach((segment: ISegmentLeaf) => {
2128
2179
  const segmentSegmentGroup = segment.segmentGroups?.pop?.();
2129
2180
  assert(
@@ -2197,7 +2248,8 @@ export class MergeTree {
2197
2248
  { op: removeOp },
2198
2249
  );
2199
2250
  } /* op.type === MergeTreeDeltaType.ANNOTATE */ else {
2200
- const props = pendingSegmentGroup.previousProps![i];
2251
+ // TODO Non null asserting, why is this not null?
2252
+ const props = pendingSegmentGroup.previousProps![i]!;
2201
2253
  const annotateOp = createAnnotateRangeOp(start, start + segment.cachedLength, props);
2202
2254
  this.annotateRange(
2203
2255
  start,
@@ -2220,7 +2272,7 @@ export class MergeTree {
2220
2272
  /**
2221
2273
  * Walk the segments up to the current segment and calculate its position
2222
2274
  */
2223
- private findRollbackPosition(segment: ISegment) {
2275
+ private findRollbackPosition(segment: ISegment): number {
2224
2276
  let segmentPosition = 0;
2225
2277
  walkAllChildSegments(this.root, (seg) => {
2226
2278
  // If we've found the desired segment, terminate the walk and return 'segmentPosition'.
@@ -2239,7 +2291,7 @@ export class MergeTree {
2239
2291
  return segmentPosition;
2240
2292
  }
2241
2293
 
2242
- public nodeUpdateLengthNewStructure(node: MergeBlock, recur = false) {
2294
+ public nodeUpdateLengthNewStructure(node: MergeBlock, recur = false): void {
2243
2295
  this.blockUpdate(node);
2244
2296
  if (this.collabWindow.collaborating) {
2245
2297
  this.localPartialsComputed = false;
@@ -2355,14 +2407,13 @@ export class MergeTree {
2355
2407
  }
2356
2408
  }
2357
2409
 
2358
- const newOrder = Array.from(affectedSegments.map(({ data }) => data));
2359
- newOrder.forEach((seg) =>
2360
- seg.localRefs?.walkReferences((lref) => lref.callbacks?.beforeSlide?.(lref)),
2361
- );
2410
+ const newOrder = Array.from(affectedSegments, ({ data }) => data);
2411
+ for (const seg of newOrder)
2412
+ seg.localRefs?.walkReferences((lref) => lref.callbacks?.beforeSlide?.(lref));
2362
2413
  const perSegmentTrackingGroups = new Map<ISegment, TrackingGroup[]>();
2363
2414
  for (const segment of newOrder) {
2364
2415
  const { trackingCollection } = segment;
2365
- const trackingGroups = Array.from(trackingCollection.trackingGroups);
2416
+ const trackingGroups = [...trackingCollection.trackingGroups];
2366
2417
  perSegmentTrackingGroups.set(segment, trackingGroups);
2367
2418
  for (const group of trackingCollection.trackingGroups) {
2368
2419
  trackingCollection.unlink(group);
@@ -2370,8 +2421,9 @@ export class MergeTree {
2370
2421
  }
2371
2422
 
2372
2423
  for (let i = 0; i < newOrder.length; i++) {
2373
- const seg = newOrder[i];
2374
- const { parent, index, ordinal } = currentOrder[i];
2424
+ // TODO Non null asserting, why is this not null?
2425
+ const seg = newOrder[i]!;
2426
+ const { parent, index, ordinal } = currentOrder[i]!;
2375
2427
  parent?.assignChild(seg, index, false);
2376
2428
  seg.ordinal = ordinal;
2377
2429
  }
@@ -2391,15 +2443,16 @@ export class MergeTree {
2391
2443
  }
2392
2444
  return depths.get(block)!;
2393
2445
  };
2394
- newOrder.forEach(computeDepth);
2395
- for (const [node] of Array.from(depths.entries()).sort((a, b) => b[1] - a[1])) {
2446
+ for (const element of newOrder) {
2447
+ computeDepth(element);
2448
+ }
2449
+ for (const [node] of [...depths.entries()].sort((a, b) => b[1] - a[1])) {
2396
2450
  if (!node.isLeaf()) {
2397
2451
  this.nodeUpdateLengthNewStructure(node);
2398
2452
  }
2399
2453
  }
2400
- newOrder.forEach((seg) =>
2401
- seg.localRefs?.walkReferences((lref) => lref.callbacks?.afterSlide?.(lref)),
2402
- );
2454
+ for (const seg of newOrder)
2455
+ seg.localRefs?.walkReferences((lref) => lref.callbacks?.afterSlide?.(lref));
2403
2456
  }
2404
2457
 
2405
2458
  /**
@@ -2426,7 +2479,7 @@ export class MergeTree {
2426
2479
  let currentRangeToNormalize = new DoublyLinkedList<ISegment>();
2427
2480
  let rangeContainsLocalSegs = false;
2428
2481
  let rangeContainsRemoteRemovedSegs = false;
2429
- const normalize = () => {
2482
+ const normalize = (): void => {
2430
2483
  if (
2431
2484
  rangeContainsLocalSegs &&
2432
2485
  rangeContainsRemoteRemovedSegs &&
@@ -2456,16 +2509,15 @@ export class MergeTree {
2456
2509
 
2457
2510
  normalize();
2458
2511
  }
2459
- private blockUpdate(block: MergeBlock) {
2512
+ private blockUpdate(block: MergeBlock): void {
2460
2513
  let len: number | undefined;
2461
2514
 
2462
- // eslint-disable-next-line import/no-deprecated
2463
2515
  const rightmostTiles = createMap<Marker>();
2464
- // eslint-disable-next-line import/no-deprecated
2465
2516
  const leftmostTiles = createMap<Marker>();
2466
2517
 
2467
2518
  for (let i = 0; i < block.childCount; i++) {
2468
- const node = block.children[i];
2519
+ // TODO Non null asserting, why is this not null?
2520
+ const node = block.children[i]!;
2469
2521
  const nodeLength = nodeTotalLength(this, node);
2470
2522
  if (nodeLength !== undefined) {
2471
2523
  len ??= 0;
@@ -2495,9 +2547,7 @@ export class MergeTree {
2495
2547
  }
2496
2548
  }
2497
2549
  } else {
2498
- // eslint-disable-next-line import/no-deprecated
2499
2550
  extend(rightmostTiles, node.rightmostTiles);
2500
- // eslint-disable-next-line import/no-deprecated
2501
2551
  extendIfUndefined(leftmostTiles, node.leftmostTiles);
2502
2552
  }
2503
2553
  }
@@ -2511,7 +2561,7 @@ export class MergeTree {
2511
2561
  seq: number,
2512
2562
  clientId: number,
2513
2563
  newStructure = false,
2514
- ) {
2564
+ ): void {
2515
2565
  let block: MergeBlock | undefined = startBlock;
2516
2566
  while (block !== undefined) {
2517
2567
  if (newStructure) {
@@ -2523,7 +2573,7 @@ export class MergeTree {
2523
2573
  }
2524
2574
  }
2525
2575
 
2526
- private blockUpdateLength(node: MergeBlock, seq: number, clientId: number) {
2576
+ private blockUpdateLength(node: MergeBlock, seq: number, clientId: number): void {
2527
2577
  this.blockUpdate(node);
2528
2578
  this.localPartialsComputed = false;
2529
2579
  if (
@@ -2561,7 +2611,7 @@ export class MergeTree {
2561
2611
  end?: number,
2562
2612
  splitRange: boolean = false,
2563
2613
  visibilitySeq: number = refSeq,
2564
- ) {
2614
+ ): void {
2565
2615
  if (splitRange) {
2566
2616
  if (start) {
2567
2617
  this.ensureIntervalBoundary(start, refSeq, clientId);
@@ -2666,7 +2716,8 @@ export class MergeTree {
2666
2716
  undefined,
2667
2717
  post === undefined
2668
2718
  ? undefined
2669
- : (block) => post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum),
2719
+ : (block): boolean =>
2720
+ post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum),
2670
2721
  );
2671
2722
  }
2672
2723
  }