@fluidframework/merge-tree 2.30.0 → 2.31.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 (308) hide show
  1. package/CHANGELOG.md +403 -399
  2. package/api-report/merge-tree.legacy.alpha.api.md +1 -0
  3. package/dist/MergeTreeTextHelper.d.ts +9 -3
  4. package/dist/MergeTreeTextHelper.d.ts.map +1 -1
  5. package/dist/MergeTreeTextHelper.js +5 -5
  6. package/dist/MergeTreeTextHelper.js.map +1 -1
  7. package/dist/client.d.ts +7 -13
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +136 -110
  10. package/dist/client.js.map +1 -1
  11. package/dist/endOfTreeSegment.d.ts +12 -8
  12. package/dist/endOfTreeSegment.d.ts.map +1 -1
  13. package/dist/endOfTreeSegment.js +2 -4
  14. package/dist/endOfTreeSegment.js.map +1 -1
  15. package/dist/index.d.ts +6 -3
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/mergeTree.d.ts +37 -23
  20. package/dist/mergeTree.d.ts.map +1 -1
  21. package/dist/mergeTree.js +400 -483
  22. package/dist/mergeTree.js.map +1 -1
  23. package/dist/mergeTreeDeltaCallback.d.ts +4 -8
  24. package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
  25. package/dist/mergeTreeDeltaCallback.js.map +1 -1
  26. package/dist/mergeTreeNodes.d.ts +32 -10
  27. package/dist/mergeTreeNodes.d.ts.map +1 -1
  28. package/dist/mergeTreeNodes.js +43 -28
  29. package/dist/mergeTreeNodes.js.map +1 -1
  30. package/dist/partialLengths.d.ts +2 -2
  31. package/dist/partialLengths.d.ts.map +1 -1
  32. package/dist/partialLengths.js +181 -109
  33. package/dist/partialLengths.js.map +1 -1
  34. package/dist/perspective.d.ts +8 -27
  35. package/dist/perspective.d.ts.map +1 -1
  36. package/dist/perspective.js +7 -67
  37. package/dist/perspective.js.map +1 -1
  38. package/dist/revertibles.d.ts.map +1 -1
  39. package/dist/revertibles.js +2 -2
  40. package/dist/revertibles.js.map +1 -1
  41. package/dist/segmentInfos.d.ts +20 -106
  42. package/dist/segmentInfos.d.ts.map +1 -1
  43. package/dist/segmentInfos.js +28 -42
  44. package/dist/segmentInfos.js.map +1 -1
  45. package/dist/segmentPropertiesManager.d.ts +1 -14
  46. package/dist/segmentPropertiesManager.d.ts.map +1 -1
  47. package/dist/segmentPropertiesManager.js +3 -17
  48. package/dist/segmentPropertiesManager.js.map +1 -1
  49. package/dist/snapshotLoader.d.ts.map +1 -1
  50. package/dist/snapshotLoader.js +62 -19
  51. package/dist/snapshotLoader.js.map +1 -1
  52. package/dist/snapshotV1.d.ts.map +1 -1
  53. package/dist/snapshotV1.js +55 -24
  54. package/dist/snapshotV1.js.map +1 -1
  55. package/dist/snapshotlegacy.d.ts.map +1 -1
  56. package/dist/snapshotlegacy.js +6 -9
  57. package/dist/snapshotlegacy.js.map +1 -1
  58. package/dist/stamps.d.ts +1 -1
  59. package/dist/stamps.js +1 -1
  60. package/dist/stamps.js.map +1 -1
  61. package/dist/test/Insertion.perf.spec.js +6 -51
  62. package/dist/test/Insertion.perf.spec.js.map +1 -1
  63. package/dist/test/PartialLengths.perf.spec.js +18 -25
  64. package/dist/test/PartialLengths.perf.spec.js.map +1 -1
  65. package/dist/test/Removal.perf.spec.js +13 -41
  66. package/dist/test/Removal.perf.spec.js.map +1 -1
  67. package/dist/test/beastTest.spec.d.ts.map +1 -1
  68. package/dist/test/beastTest.spec.js +41 -66
  69. package/dist/test/beastTest.spec.js.map +1 -1
  70. package/dist/test/client.annotateMarker.spec.js +1 -11
  71. package/dist/test/client.annotateMarker.spec.js.map +1 -1
  72. package/dist/test/client.applyMsg.spec.js +14 -14
  73. package/dist/test/client.applyMsg.spec.js.map +1 -1
  74. package/dist/test/client.getPosition.spec.js +1 -1
  75. package/dist/test/client.getPosition.spec.js.map +1 -1
  76. package/dist/test/client.localReference.spec.js +1 -1
  77. package/dist/test/client.localReference.spec.js.map +1 -1
  78. package/dist/test/client.rollback.spec.js +49 -58
  79. package/dist/test/client.rollback.spec.js.map +1 -1
  80. package/dist/test/client.rollbackFarm.spec.js +1 -1
  81. package/dist/test/client.rollbackFarm.spec.js.map +1 -1
  82. package/dist/test/client.searchForMarker.spec.js +4 -21
  83. package/dist/test/client.searchForMarker.spec.js.map +1 -1
  84. package/dist/test/index.d.ts +2 -2
  85. package/dist/test/index.d.ts.map +1 -1
  86. package/dist/test/index.js +2 -6
  87. package/dist/test/index.js.map +1 -1
  88. package/dist/test/mergeTree.annotate.deltaCallback.spec.js +14 -59
  89. package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  90. package/dist/test/mergeTree.annotate.spec.js +47 -63
  91. package/dist/test/mergeTree.annotate.spec.js.map +1 -1
  92. package/dist/test/mergeTree.insert.deltaCallback.spec.js +9 -62
  93. package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  94. package/dist/test/mergeTree.insertingWalk.spec.js +59 -125
  95. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
  96. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +12 -93
  97. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  98. package/dist/test/mergeTree.markRangeRemoved.spec.js +10 -7
  99. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  100. package/dist/test/mergeTree.walk.spec.js +2 -14
  101. package/dist/test/mergeTree.walk.spec.js.map +1 -1
  102. package/dist/test/mergeTreeOperationRunner.js +2 -2
  103. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  104. package/dist/test/obliterate.concurrent.spec.js +18 -23
  105. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  106. package/dist/test/obliterate.partialLength.spec.js +166 -136
  107. package/dist/test/obliterate.partialLength.spec.js.map +1 -1
  108. package/dist/test/obliterate.spec.js +16 -126
  109. package/dist/test/obliterate.spec.js.map +1 -1
  110. package/dist/test/partialLength.spec.js +28 -196
  111. package/dist/test/partialLength.spec.js.map +1 -1
  112. package/dist/test/perspective.spec.js +34 -0
  113. package/dist/test/perspective.spec.js.map +1 -1
  114. package/dist/test/propertyManager.spec.js +1 -1
  115. package/dist/test/propertyManager.spec.js.map +1 -1
  116. package/dist/test/resetPendingSegmentsToOp.spec.js +0 -2
  117. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  118. package/dist/test/segmentGroupCollection.spec.js +10 -4
  119. package/dist/test/segmentGroupCollection.spec.js.map +1 -1
  120. package/dist/test/testClient.d.ts +1 -0
  121. package/dist/test/testClient.d.ts.map +1 -1
  122. package/dist/test/testClient.js +16 -26
  123. package/dist/test/testClient.js.map +1 -1
  124. package/dist/test/testClientLogger.d.ts.map +1 -1
  125. package/dist/test/testClientLogger.js +3 -10
  126. package/dist/test/testClientLogger.js.map +1 -1
  127. package/dist/test/testServer.d.ts +2 -1
  128. package/dist/test/testServer.d.ts.map +1 -1
  129. package/dist/test/testServer.js +7 -5
  130. package/dist/test/testServer.js.map +1 -1
  131. package/dist/test/testUtils.d.ts +36 -56
  132. package/dist/test/testUtils.d.ts.map +1 -1
  133. package/dist/test/testUtils.js +68 -77
  134. package/dist/test/testUtils.js.map +1 -1
  135. package/dist/test/text.d.ts +2 -2
  136. package/dist/test/text.d.ts.map +1 -1
  137. package/dist/test/text.js +5 -2
  138. package/dist/test/text.js.map +1 -1
  139. package/dist/textSegment.d.ts +0 -6
  140. package/dist/textSegment.d.ts.map +1 -1
  141. package/dist/textSegment.js.map +1 -1
  142. package/dist/zamboni.d.ts.map +1 -1
  143. package/dist/zamboni.js +53 -26
  144. package/dist/zamboni.js.map +1 -1
  145. package/lib/MergeTreeTextHelper.d.ts +9 -3
  146. package/lib/MergeTreeTextHelper.d.ts.map +1 -1
  147. package/lib/MergeTreeTextHelper.js +5 -5
  148. package/lib/MergeTreeTextHelper.js.map +1 -1
  149. package/lib/client.d.ts +7 -13
  150. package/lib/client.d.ts.map +1 -1
  151. package/lib/client.js +117 -116
  152. package/lib/client.js.map +1 -1
  153. package/lib/endOfTreeSegment.d.ts +12 -8
  154. package/lib/endOfTreeSegment.d.ts.map +1 -1
  155. package/lib/endOfTreeSegment.js +2 -4
  156. package/lib/endOfTreeSegment.js.map +1 -1
  157. package/lib/index.d.ts +6 -3
  158. package/lib/index.d.ts.map +1 -1
  159. package/lib/index.js +1 -1
  160. package/lib/index.js.map +1 -1
  161. package/lib/mergeTree.d.ts +37 -23
  162. package/lib/mergeTree.d.ts.map +1 -1
  163. package/lib/mergeTree.js +381 -488
  164. package/lib/mergeTree.js.map +1 -1
  165. package/lib/mergeTreeDeltaCallback.d.ts +4 -8
  166. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  167. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  168. package/lib/mergeTreeNodes.d.ts +32 -10
  169. package/lib/mergeTreeNodes.d.ts.map +1 -1
  170. package/lib/mergeTreeNodes.js +42 -29
  171. package/lib/mergeTreeNodes.js.map +1 -1
  172. package/lib/partialLengths.d.ts +2 -2
  173. package/lib/partialLengths.d.ts.map +1 -1
  174. package/lib/partialLengths.js +160 -111
  175. package/lib/partialLengths.js.map +1 -1
  176. package/lib/perspective.d.ts +8 -27
  177. package/lib/perspective.d.ts.map +1 -1
  178. package/lib/perspective.js +8 -68
  179. package/lib/perspective.js.map +1 -1
  180. package/lib/revertibles.d.ts.map +1 -1
  181. package/lib/revertibles.js +2 -2
  182. package/lib/revertibles.js.map +1 -1
  183. package/lib/segmentInfos.d.ts +20 -106
  184. package/lib/segmentInfos.d.ts.map +1 -1
  185. package/lib/segmentInfos.js +26 -37
  186. package/lib/segmentInfos.js.map +1 -1
  187. package/lib/segmentPropertiesManager.d.ts +1 -14
  188. package/lib/segmentPropertiesManager.d.ts.map +1 -1
  189. package/lib/segmentPropertiesManager.js +2 -16
  190. package/lib/segmentPropertiesManager.js.map +1 -1
  191. package/lib/snapshotLoader.d.ts.map +1 -1
  192. package/lib/snapshotLoader.js +39 -19
  193. package/lib/snapshotLoader.js.map +1 -1
  194. package/lib/snapshotV1.d.ts.map +1 -1
  195. package/lib/snapshotV1.js +34 -26
  196. package/lib/snapshotV1.js.map +1 -1
  197. package/lib/snapshotlegacy.d.ts.map +1 -1
  198. package/lib/snapshotlegacy.js +7 -10
  199. package/lib/snapshotlegacy.js.map +1 -1
  200. package/lib/stamps.d.ts +1 -1
  201. package/lib/stamps.js +1 -1
  202. package/lib/stamps.js.map +1 -1
  203. package/lib/test/Insertion.perf.spec.js +6 -51
  204. package/lib/test/Insertion.perf.spec.js.map +1 -1
  205. package/lib/test/PartialLengths.perf.spec.js +18 -25
  206. package/lib/test/PartialLengths.perf.spec.js.map +1 -1
  207. package/lib/test/Removal.perf.spec.js +13 -41
  208. package/lib/test/Removal.perf.spec.js.map +1 -1
  209. package/lib/test/beastTest.spec.d.ts.map +1 -1
  210. package/lib/test/beastTest.spec.js +42 -67
  211. package/lib/test/beastTest.spec.js.map +1 -1
  212. package/lib/test/client.annotateMarker.spec.js +1 -11
  213. package/lib/test/client.annotateMarker.spec.js.map +1 -1
  214. package/lib/test/client.applyMsg.spec.js +14 -14
  215. package/lib/test/client.applyMsg.spec.js.map +1 -1
  216. package/lib/test/client.getPosition.spec.js +1 -1
  217. package/lib/test/client.getPosition.spec.js.map +1 -1
  218. package/lib/test/client.localReference.spec.js +1 -1
  219. package/lib/test/client.localReference.spec.js.map +1 -1
  220. package/lib/test/client.rollback.spec.js +50 -59
  221. package/lib/test/client.rollback.spec.js.map +1 -1
  222. package/lib/test/client.rollbackFarm.spec.js +1 -1
  223. package/lib/test/client.rollbackFarm.spec.js.map +1 -1
  224. package/lib/test/client.searchForMarker.spec.js +4 -21
  225. package/lib/test/client.searchForMarker.spec.js.map +1 -1
  226. package/lib/test/index.d.ts +2 -2
  227. package/lib/test/index.d.ts.map +1 -1
  228. package/lib/test/index.js +1 -1
  229. package/lib/test/index.js.map +1 -1
  230. package/lib/test/mergeTree.annotate.deltaCallback.spec.js +15 -60
  231. package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  232. package/lib/test/mergeTree.annotate.spec.js +48 -64
  233. package/lib/test/mergeTree.annotate.spec.js.map +1 -1
  234. package/lib/test/mergeTree.insert.deltaCallback.spec.js +10 -63
  235. package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  236. package/lib/test/mergeTree.insertingWalk.spec.js +61 -127
  237. package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
  238. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +13 -94
  239. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  240. package/lib/test/mergeTree.markRangeRemoved.spec.js +10 -7
  241. package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  242. package/lib/test/mergeTree.walk.spec.js +2 -14
  243. package/lib/test/mergeTree.walk.spec.js.map +1 -1
  244. package/lib/test/mergeTreeOperationRunner.js +3 -3
  245. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  246. package/lib/test/obliterate.concurrent.spec.js +18 -23
  247. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  248. package/lib/test/obliterate.partialLength.spec.js +167 -137
  249. package/lib/test/obliterate.partialLength.spec.js.map +1 -1
  250. package/lib/test/obliterate.spec.js +17 -127
  251. package/lib/test/obliterate.spec.js.map +1 -1
  252. package/lib/test/partialLength.spec.js +29 -197
  253. package/lib/test/partialLength.spec.js.map +1 -1
  254. package/lib/test/perspective.spec.js +34 -0
  255. package/lib/test/perspective.spec.js.map +1 -1
  256. package/lib/test/propertyManager.spec.js +2 -2
  257. package/lib/test/propertyManager.spec.js.map +1 -1
  258. package/lib/test/resetPendingSegmentsToOp.spec.js +0 -2
  259. package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  260. package/lib/test/segmentGroupCollection.spec.js +10 -4
  261. package/lib/test/segmentGroupCollection.spec.js.map +1 -1
  262. package/lib/test/testClient.d.ts +1 -0
  263. package/lib/test/testClient.d.ts.map +1 -1
  264. package/lib/test/testClient.js +18 -28
  265. package/lib/test/testClient.js.map +1 -1
  266. package/lib/test/testClientLogger.d.ts.map +1 -1
  267. package/lib/test/testClientLogger.js +3 -10
  268. package/lib/test/testClientLogger.js.map +1 -1
  269. package/lib/test/testServer.d.ts +2 -1
  270. package/lib/test/testServer.d.ts.map +1 -1
  271. package/lib/test/testServer.js +7 -5
  272. package/lib/test/testServer.js.map +1 -1
  273. package/lib/test/testUtils.d.ts +36 -56
  274. package/lib/test/testUtils.d.ts.map +1 -1
  275. package/lib/test/testUtils.js +66 -48
  276. package/lib/test/testUtils.js.map +1 -1
  277. package/lib/test/text.d.ts +2 -2
  278. package/lib/test/text.d.ts.map +1 -1
  279. package/lib/test/text.js +6 -3
  280. package/lib/test/text.js.map +1 -1
  281. package/lib/textSegment.d.ts +0 -6
  282. package/lib/textSegment.d.ts.map +1 -1
  283. package/lib/textSegment.js.map +1 -1
  284. package/lib/tsdoc-metadata.json +1 -1
  285. package/lib/zamboni.d.ts.map +1 -1
  286. package/lib/zamboni.js +32 -28
  287. package/lib/zamboni.js.map +1 -1
  288. package/package.json +17 -20
  289. package/src/MergeTreeTextHelper.ts +17 -12
  290. package/src/client.ts +141 -197
  291. package/src/endOfTreeSegment.ts +11 -8
  292. package/src/index.ts +4 -3
  293. package/src/mergeTree.ts +482 -633
  294. package/src/mergeTreeDeltaCallback.ts +4 -8
  295. package/src/mergeTreeNodes.ts +66 -45
  296. package/src/partialLengths.ts +181 -137
  297. package/src/perspective.ts +17 -95
  298. package/src/revertibles.ts +2 -7
  299. package/src/segmentInfos.ts +48 -141
  300. package/src/segmentPropertiesManager.ts +2 -16
  301. package/src/snapshotLoader.ts +62 -30
  302. package/src/snapshotV1.ts +36 -28
  303. package/src/snapshotlegacy.ts +7 -16
  304. package/src/stamps.ts +1 -1
  305. package/src/textSegment.ts +0 -13
  306. package/src/zamboni.ts +38 -32
  307. package/tsconfig.json +1 -0
  308. package/prettier.config.cjs +0 -8
@@ -3,10 +3,11 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IIntegerRange } from "./client.js";
7
- import { MergeTree } from "./mergeTree.js";
8
- import { ISegmentPrivate } from "./mergeTreeNodes.js";
9
- import { IMergeTreeTextHelper, TextSegment } from "./textSegment.js";
6
+ import type { IIntegerRange } from "./client.js";
7
+ import type { MergeTree } from "./mergeTree.js";
8
+ import type { ISegmentPrivate } from "./mergeTreeNodes.js";
9
+ import type { Perspective } from "./perspective.js";
10
+ import { TextSegment } from "./textSegment.js";
10
11
 
11
12
  interface ITextAccumulator {
12
13
  textSegment: TextSegment;
@@ -14,24 +15,29 @@ interface ITextAccumulator {
14
15
  parallelArrays?: boolean;
15
16
  }
16
17
 
18
+ /**
19
+ * @internal
20
+ */
21
+ export interface IMergeTreeTextHelper {
22
+ getText(perspective: Perspective, placeholder: string, start?: number, end?: number): string;
23
+ }
24
+
17
25
  export class MergeTreeTextHelper implements IMergeTreeTextHelper {
18
26
  constructor(private readonly mergeTree: MergeTree) {}
19
27
 
20
28
  public getText(
21
- refSeq: number,
22
- clientId: number,
29
+ perspective: Perspective,
23
30
  placeholder = "",
24
31
  start?: number,
25
32
  end?: number,
26
33
  ): string {
27
- const range = this.getValidRange(start, end, refSeq, clientId);
34
+ const range = this.getValidRange(start, end, perspective);
28
35
 
29
36
  const accum: ITextAccumulator = { textSegment: new TextSegment(""), placeholder };
30
37
 
31
38
  this.mergeTree.mapRange<ITextAccumulator>(
32
39
  gatherText,
33
- refSeq,
34
- clientId,
40
+ perspective,
35
41
  accum,
36
42
  range.start,
37
43
  range.end,
@@ -42,11 +48,10 @@ export class MergeTreeTextHelper implements IMergeTreeTextHelper {
42
48
  private getValidRange(
43
49
  start: number | undefined,
44
50
  end: number | undefined,
45
- refSeq: number,
46
- clientId: number,
51
+ perspective: Perspective,
47
52
  ): IIntegerRange {
48
53
  const range: IIntegerRange = {
49
- end: end ?? this.mergeTree.getLength(refSeq, clientId),
54
+ end: end ?? this.mergeTree.getLength(perspective),
50
55
  start: start ?? 0,
51
56
  };
52
57
  return range;
package/src/client.ts CHANGED
@@ -25,21 +25,17 @@ import {
25
25
  UsageError,
26
26
  } from "@fluidframework/telemetry-utils/internal";
27
27
 
28
- import { MergeTreeTextHelper } from "./MergeTreeTextHelper.js";
28
+ import { MergeTreeTextHelper, type IMergeTreeTextHelper } from "./MergeTreeTextHelper.js";
29
29
  import { DoublyLinkedList, RedBlackTree } from "./collections/index.js";
30
- import {
31
- NonCollabClient,
32
- UnassignedSequenceNumber,
33
- UniversalSequenceNumber,
34
- } from "./constants.js";
30
+ import { NonCollabClient, UniversalSequenceNumber } from "./constants.js";
35
31
  import { LocalReferencePosition, SlidingPreference } from "./localReference.js";
36
32
  import {
37
33
  MergeTree,
38
34
  errorIfOptionNotTrue,
35
+ isRemovedAndAcked,
39
36
  type IMergeTreeOptionsInternal,
40
37
  } from "./mergeTree.js";
41
38
  import type {
42
- IMergeTreeClientSequenceArgs,
43
39
  IMergeTreeDeltaCallbackArgs,
44
40
  IMergeTreeDeltaOpArgs,
45
41
  IMergeTreeMaintenanceCallbackArgs,
@@ -59,7 +55,6 @@ import {
59
55
  createAdjustRangeOp,
60
56
  createAnnotateMarkerOp,
61
57
  createAnnotateRangeOp,
62
- // eslint-disable-next-line import/no-deprecated
63
58
  createGroupOp,
64
59
  createInsertSegmentOp,
65
60
  createObliterateRangeOp,
@@ -84,21 +79,26 @@ import {
84
79
  type IMergeTreeAnnotateAdjustMsg,
85
80
  type IMergeTreeObliterateSidedMsg,
86
81
  } from "./ops.js";
82
+ import {
83
+ LocalReconnectingPerspective,
84
+ PriorPerspective,
85
+ type Perspective,
86
+ } from "./perspective.js";
87
87
  import { PropertySet, type MapLike } from "./properties.js";
88
88
  import { DetachedReferencePosition, ReferencePosition } from "./referencePositions.js";
89
89
  import {
90
90
  isInserted,
91
- isMoved,
92
91
  isRemoved,
93
92
  overwriteInfo,
94
- toMoveInfo,
95
- type IInsertionInfo,
93
+ toRemovalInfo,
94
+ type IHasInsertionInfo,
96
95
  } from "./segmentInfos.js";
97
96
  import { Side, type InteriorSequencePlace } from "./sequencePlace.js";
98
97
  import { SnapshotLoader } from "./snapshotLoader.js";
99
98
  import { SnapshotV1 } from "./snapshotV1.js";
100
99
  import { SnapshotLegacy } from "./snapshotlegacy.js";
101
- import { IMergeTreeTextHelper } from "./textSegment.js";
100
+ import type { OperationStamp } from "./stamps.js";
101
+ import * as opstampUtils from "./stamps.js";
102
102
 
103
103
  type IMergeTreeDeltaRemoteOpArgs = Omit<IMergeTreeDeltaOpArgs, "sequencedMessage"> &
104
104
  Required<Pick<IMergeTreeDeltaOpArgs, "sequencedMessage">>;
@@ -371,8 +371,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
371
371
  ): void {
372
372
  this._mergeTree.mapRange(
373
373
  handler,
374
- this.getCurrentSeq(),
375
- this.getClientId(),
374
+ this._mergeTree.localPerspective,
376
375
  accum,
377
376
  start,
378
377
  end,
@@ -401,12 +400,17 @@ export class Client extends TypedEventEmitter<IClientEvents> {
401
400
  ): void {
402
401
  let localInserts = 0;
403
402
  let localRemoves = 0;
403
+ let localObliterates = 0;
404
404
  walkAllChildSegments(this._mergeTree.root, (seg: ISegmentPrivate) => {
405
- if (isInserted(seg) && seg.seq === UnassignedSequenceNumber) {
405
+ if (isInserted(seg) && opstampUtils.isLocal(seg.insert)) {
406
406
  localInserts++;
407
407
  }
408
- if (isRemoved(seg) && seg.removedSeq === UnassignedSequenceNumber) {
409
- localRemoves++;
408
+ if (isRemoved(seg) && opstampUtils.isLocal(seg.removes[seg.removes.length - 1])) {
409
+ if (seg.removes[seg.removes.length - 1].type === "setRemove") {
410
+ localRemoves++;
411
+ } else {
412
+ localObliterates++;
413
+ }
410
414
  }
411
415
  // Only serialize segments that have not been removed.
412
416
  if (!isRemoved(seg)) {
@@ -420,6 +424,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
420
424
  eventName: "LocalEditsInProcessGCData",
421
425
  localInserts,
422
426
  localRemoves,
427
+ localObliterates,
423
428
  });
424
429
  }
425
430
  }
@@ -437,12 +442,12 @@ export class Client extends TypedEventEmitter<IClientEvents> {
437
442
  if (!isSegmentLeaf(segment)) {
438
443
  return -1;
439
444
  }
440
- return this._mergeTree.getPosition(
441
- segment,
442
- this.getCurrentSeq(),
443
- this.getClientId(),
444
- localSeq,
445
- );
445
+
446
+ const perspective =
447
+ localSeq === undefined
448
+ ? this._mergeTree.localPerspective
449
+ : new LocalReconnectingPerspective(this.getCurrentSeq(), this.getClientId(), localSeq);
450
+ return this._mergeTree.getPosition(segment, perspective);
446
451
  }
447
452
 
448
453
  /**
@@ -504,7 +509,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
504
509
  * @param relativePos - Id of marker (may be indirect) and whether position is before or after marker.
505
510
  */
506
511
  public posFromRelativePos(relativePos: IRelativePosition): number {
507
- return this._mergeTree.posFromRelativePos(relativePos);
512
+ return this._mergeTree.posFromRelativePos(relativePos, this._mergeTree.localPerspective);
508
513
  }
509
514
 
510
515
  public getMarkerFromId(id: string): ISegment | undefined {
@@ -514,66 +519,78 @@ export class Client extends TypedEventEmitter<IClientEvents> {
514
519
  /**
515
520
  * Revert an op
516
521
  */
517
- public rollback?(op: unknown, localOpMetadata: unknown): void {
522
+ public rollback(op: unknown, localOpMetadata: unknown): void {
518
523
  this._mergeTree.rollback(op as IMergeTreeDeltaOp, localOpMetadata as SegmentGroup);
519
524
  }
520
525
 
521
526
  private applyObliterateRangeOp(opArgs: IMergeTreeDeltaOpArgs): void {
527
+ const { op, sequencedMessage } = opArgs;
522
528
  assert(
523
- opArgs.op.type === MergeTreeDeltaType.OBLITERATE ||
524
- opArgs.op.type === MergeTreeDeltaType.OBLITERATE_SIDED,
529
+ op.type === MergeTreeDeltaType.OBLITERATE ||
530
+ op.type === MergeTreeDeltaType.OBLITERATE_SIDED,
525
531
  0x866 /* Unexpected op type on range obliterate! */,
526
532
  );
527
- const op = opArgs.op;
528
- const clientArgs = this.getClientSequenceArgs(opArgs);
533
+ const perspective = this.getOperationPerspective(sequencedMessage);
534
+ const stamp = this.getOperationStamp(sequencedMessage);
535
+
529
536
  if (this._mergeTree.options?.mergeTreeEnableSidedObliterate) {
530
- const { start, end } = this.getValidSidedRange(op, clientArgs);
531
- this._mergeTree.obliterateRange(
532
- start,
533
- end,
534
- clientArgs.referenceSequenceNumber,
535
- clientArgs.clientId,
536
- clientArgs.sequenceNumber,
537
- opArgs,
538
- );
537
+ const { start, end } = this.getValidSidedRange(op, perspective);
538
+ this._mergeTree.obliterateRange(start, end, perspective, stamp, opArgs);
539
539
  } else {
540
540
  assert(
541
541
  op.type === MergeTreeDeltaType.OBLITERATE,
542
542
  0xa43 /* Unexpected sided obliterate while mergeTreeEnableSidedObliterate is disabled */,
543
543
  );
544
- const range = this.getValidOpRange(op, clientArgs);
545
- this._mergeTree.obliterateRange(
546
- range.start,
547
- range.end,
548
- clientArgs.referenceSequenceNumber,
549
- clientArgs.clientId,
550
- clientArgs.sequenceNumber,
551
- opArgs,
552
- );
544
+ const { start, end } = this.getValidOpRange(op, perspective);
545
+ this._mergeTree.obliterateRange(start, end, perspective, stamp, opArgs);
553
546
  }
554
547
  }
555
548
 
549
+ private getOperationPerspective(
550
+ sequencedMessage: ISequencedDocumentMessage | undefined,
551
+ ): Perspective {
552
+ if (!sequencedMessage) {
553
+ return this._mergeTree.localPerspective;
554
+ }
555
+
556
+ const clientId = this.getOrAddShortClientIdFromMessage(sequencedMessage);
557
+ const { referenceSequenceNumber: refSeq } = sequencedMessage;
558
+ return new PriorPerspective(refSeq, clientId);
559
+ }
560
+
561
+ /**
562
+ * Returns the operation stamp to apply for a change, minting a new one local one if necessary.
563
+ */
564
+ private getOperationStamp(
565
+ sequencedMessage: ISequencedDocumentMessage | undefined,
566
+ ): OperationStamp {
567
+ if (!sequencedMessage) {
568
+ return this.getCollabWindow().mintNextLocalOperationStamp();
569
+ }
570
+
571
+ const { sequenceNumber: seq } = sequencedMessage;
572
+ const clientId = this.getOrAddShortClientIdFromMessage(sequencedMessage);
573
+ return {
574
+ seq,
575
+ clientId,
576
+ };
577
+ }
578
+
556
579
  /**
557
580
  * Performs the remove based on the provided op
558
581
  * @param opArgs - The ops args for the op
559
582
  */
560
583
  private applyRemoveRangeOp(opArgs: IMergeTreeDeltaOpArgs): void {
584
+ const { op, sequencedMessage } = opArgs;
561
585
  assert(
562
- opArgs.op.type === MergeTreeDeltaType.REMOVE,
586
+ op.type === MergeTreeDeltaType.REMOVE,
563
587
  0x02d /* "Unexpected op type on range remove!" */,
564
588
  );
565
- const op = opArgs.op;
566
- const clientArgs = this.getClientSequenceArgs(opArgs);
567
- const range = this.getValidOpRange(op, clientArgs);
568
-
569
- this._mergeTree.markRangeRemoved(
570
- range.start,
571
- range.end,
572
- clientArgs.referenceSequenceNumber,
573
- clientArgs.clientId,
574
- clientArgs.sequenceNumber,
575
- opArgs,
576
- );
589
+ const perspective = this.getOperationPerspective(sequencedMessage);
590
+ const stamp = this.getOperationStamp(sequencedMessage);
591
+ const range = this.getValidOpRange(op, perspective);
592
+
593
+ this._mergeTree.markRangeRemoved(range.start, range.end, perspective, stamp, opArgs);
577
594
  }
578
595
 
579
596
  /**
@@ -581,23 +598,16 @@ export class Client extends TypedEventEmitter<IClientEvents> {
581
598
  * @param opArgs - The ops args for the op
582
599
  */
583
600
  private applyAnnotateRangeOp(opArgs: IMergeTreeDeltaOpArgs): void {
601
+ const { op, sequencedMessage } = opArgs;
584
602
  assert(
585
- opArgs.op.type === MergeTreeDeltaType.ANNOTATE,
603
+ op.type === MergeTreeDeltaType.ANNOTATE,
586
604
  0x02e /* "Unexpected op type on range annotate!" */,
587
605
  );
588
- const op = opArgs.op;
589
- const clientArgs = this.getClientSequenceArgs(opArgs);
590
- const range = this.getValidOpRange(op, clientArgs);
591
-
592
- this._mergeTree.annotateRange(
593
- range.start,
594
- range.end,
595
- op,
596
- clientArgs.referenceSequenceNumber,
597
- clientArgs.clientId,
598
- clientArgs.sequenceNumber,
599
- opArgs,
600
- );
606
+ const perspective = this.getOperationPerspective(sequencedMessage);
607
+ const stamp = this.getOperationStamp(sequencedMessage);
608
+ const range = this.getValidOpRange(op, perspective);
609
+
610
+ this._mergeTree.annotateRange(range.start, range.end, op, perspective, stamp, opArgs);
601
611
  }
602
612
 
603
613
  /**
@@ -606,25 +616,19 @@ export class Client extends TypedEventEmitter<IClientEvents> {
606
616
  * @returns True if the insert was applied. False if it could not be.
607
617
  */
608
618
  private applyInsertOp(opArgs: IMergeTreeDeltaOpArgs): void {
619
+ const { op, sequencedMessage } = opArgs;
609
620
  assert(
610
- opArgs.op.type === MergeTreeDeltaType.INSERT,
621
+ op.type === MergeTreeDeltaType.INSERT,
611
622
  0x02f /* "Unexpected op type on range insert!" */,
612
623
  );
613
- const op = opArgs.op;
614
- const clientArgs = this.getClientSequenceArgs(opArgs);
615
- const range = this.getValidOpRange(op, clientArgs);
624
+ const perspective = this.getOperationPerspective(sequencedMessage);
625
+ const stamp = this.getOperationStamp(sequencedMessage);
626
+ const range = this.getValidOpRange(op, perspective);
616
627
 
617
628
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
618
629
  const segments = [this.specToSegment(op.seg)];
619
630
 
620
- this._mergeTree.insertSegments(
621
- range.start,
622
- segments,
623
- clientArgs.referenceSequenceNumber,
624
- clientArgs.clientId,
625
- clientArgs.sequenceNumber,
626
- opArgs,
627
- );
631
+ this._mergeTree.insertSegments(range.start, segments, perspective, stamp, opArgs);
628
632
  }
629
633
 
630
634
  /**
@@ -636,7 +640,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
636
640
  private getValidSidedRange(
637
641
  // eslint-disable-next-line import/no-deprecated
638
642
  op: IMergeTreeObliterateSidedMsg | IMergeTreeObliterateMsg,
639
- clientArgs: IMergeTreeClientSequenceArgs,
643
+ perspective: Perspective,
640
644
  ): {
641
645
  start: InteriorSequencePlace;
642
646
  end: InteriorSequencePlace;
@@ -662,11 +666,8 @@ export class Client extends TypedEventEmitter<IClientEvents> {
662
666
  }
663
667
 
664
668
  // Validate if local op
665
- if (clientArgs.clientId === this.getClientId()) {
666
- const length = this._mergeTree.getLength(
667
- this.getCollabWindow().currentSeq,
668
- this.getClientId(),
669
- );
669
+ if (perspective.clientId === this.getClientId()) {
670
+ const length = this._mergeTree.getLength(this._mergeTree.localPerspective);
670
671
  if (start !== undefined && (start.pos >= length || start.pos < 0)) {
671
672
  // start out of bounds
672
673
  invalidPositions.push("start");
@@ -719,28 +720,20 @@ export class Client extends TypedEventEmitter<IClientEvents> {
719
720
  | IMergeTreeRemoveMsg
720
721
  // eslint-disable-next-line import/no-deprecated
721
722
  | IMergeTreeObliterateMsg,
722
- clientArgs: IMergeTreeClientSequenceArgs,
723
+ perspective: Perspective,
723
724
  ): IIntegerRange {
724
725
  let start: number | undefined = op.pos1;
725
726
  if (start === undefined && op.relativePos1) {
726
- start = this._mergeTree.posFromRelativePos(
727
- op.relativePos1,
728
- clientArgs.referenceSequenceNumber,
729
- clientArgs.clientId,
730
- );
727
+ start = this._mergeTree.posFromRelativePos(op.relativePos1, perspective);
731
728
  }
732
729
 
733
730
  let end: number | undefined = op.pos2;
734
731
  if (end === undefined && op.relativePos2) {
735
- end = this._mergeTree.posFromRelativePos(
736
- op.relativePos2,
737
- clientArgs.referenceSequenceNumber,
738
- clientArgs.clientId,
739
- );
732
+ end = this._mergeTree.posFromRelativePos(op.relativePos2, perspective);
740
733
  }
741
734
 
742
735
  // Validate if local op
743
- if (clientArgs.clientId === this.getClientId()) {
736
+ if (perspective.clientId === this.getClientId()) {
744
737
  const length = this.getLength();
745
738
 
746
739
  const invalidPositions: string[] = [];
@@ -787,45 +780,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
787
780
  return { start: start!, end: end! };
788
781
  }
789
782
 
790
- /**
791
- * Gets the client args from the op if remote, otherwise uses the local clients info
792
- * @param sequencedMessage - The sequencedMessage to get the client sequence args for
793
- */
794
- private getClientSequenceArgsForMessage(
795
- sequencedMessage:
796
- | ISequencedDocumentMessage
797
- | Pick<ISequencedDocumentMessage, "referenceSequenceNumber" | "clientId">
798
- | undefined,
799
- ): IMergeTreeClientSequenceArgs {
800
- // If there this no sequenced message, then the op is local
801
- // and unacked, so use this clients sequenced args
802
- //
803
- if (sequencedMessage) {
804
- return {
805
- clientId: this.getOrAddShortClientIdFromMessage(sequencedMessage),
806
- referenceSequenceNumber: sequencedMessage.referenceSequenceNumber,
807
- // Note: return value satisfies overload signatures despite the cast, as if input argument doesn't contain sequenceNumber,
808
- // return value isn't expected to have it either.
809
- sequenceNumber: (sequencedMessage as ISequencedDocumentMessage).sequenceNumber,
810
- };
811
- } else {
812
- const segWindow = this.getCollabWindow();
813
- return {
814
- clientId: segWindow.clientId,
815
- referenceSequenceNumber: segWindow.currentSeq,
816
- sequenceNumber: this.getLocalSequenceNumber(),
817
- };
818
- }
819
- }
820
-
821
- /**
822
- * Gets the client args from the op if remote, otherwise uses the local clients info
823
- * @param opArgs - The op arg to get the client sequence args for
824
- */
825
- private getClientSequenceArgs(opArgs: IMergeTreeDeltaOpArgs): IMergeTreeClientSequenceArgs {
826
- return this.getClientSequenceArgsForMessage(opArgs.sequencedMessage);
827
- }
828
-
829
783
  private ackPendingSegment(opArgs: IMergeTreeDeltaRemoteOpArgs): void {
830
784
  if (opArgs.op.type === MergeTreeDeltaType.GROUP) {
831
785
  for (const memberOp of opArgs.op.ops) {
@@ -884,7 +838,8 @@ export class Client extends TypedEventEmitter<IClientEvents> {
884
838
  if (!isSegmentLeaf(segment)) {
885
839
  throw new UsageError(UNBOUND_SEGMENT_ERROR);
886
840
  }
887
- return this._mergeTree.getPosition(segment, currentSeq, clientId, localSeq);
841
+ const perspective = new LocalReconnectingPerspective(currentSeq, clientId, localSeq);
842
+ return this._mergeTree.getPosition(segment, perspective);
888
843
  }
889
844
 
890
845
  private resetPendingDeltaToOps(
@@ -942,14 +897,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
942
897
  // if the segment has been removed or obliterated, there's no need to send the annotate op
943
898
  // unless the remove was local, in which case the annotate must have come
944
899
  // before the remove
945
- if (
946
- (!isRemoved(segment) ||
947
- (segment.localRemovedSeq !== undefined &&
948
- segment.removedSeq === UnassignedSequenceNumber)) &&
949
- (!isMoved(segment) ||
950
- (segment.localMovedSeq !== undefined &&
951
- segment.movedSeq === UnassignedSequenceNumber))
952
- ) {
900
+ if (!isRemovedAndAcked(segment)) {
953
901
  newOp =
954
902
  resetOp.props === undefined
955
903
  ? createAdjustRangeOp(
@@ -968,28 +916,33 @@ export class Client extends TypedEventEmitter<IClientEvents> {
968
916
 
969
917
  case MergeTreeDeltaType.INSERT: {
970
918
  assert(
971
- isInserted(segment) && segment.seq === UnassignedSequenceNumber,
919
+ isInserted(segment) && opstampUtils.isLocal(segment.insert),
972
920
  0x037 /* "Segment already has assigned sequence number" */,
973
921
  );
974
- const moveInfo = toMoveInfo(segment);
922
+ const removeInfo = toRemovalInfo(segment);
975
923
 
976
- if (moveInfo !== undefined) {
924
+ if (removeInfo !== undefined && opstampUtils.isAcked(removeInfo.removes[0])) {
925
+ assert(
926
+ removeInfo.removes[0].type === "sliceRemove",
927
+ 0xb5c /* Remove on insertion must be caused by obliterate. */,
928
+ );
977
929
  errorIfOptionNotTrue(
978
930
  this._mergeTree.options,
979
931
  "mergeTreeEnableObliterateReconnect",
980
932
  );
981
- if (moveInfo.movedSeq !== UnassignedSequenceNumber) {
982
- // the segment was remotely obliterated, so is considered removed
983
- // we set the seq to the universal seq and remove the local seq,
984
- // so its length is not considered for subsequent local changes
985
- // this allows us to not send the op as even the local client will ignore the segment
986
- overwriteInfo<IInsertionInfo>(segment, {
933
+ // the segment was remotely obliterated, so is considered removed
934
+ // we set the seq to the universal seq and remove the local seq,
935
+ // so its length is not considered for subsequent local changes
936
+ // this allows us to not send the op as even the local client will ignore the segment
937
+ overwriteInfo<IHasInsertionInfo>(segment, {
938
+ insert: {
939
+ type: "insert",
987
940
  seq: UniversalSequenceNumber,
988
941
  localSeq: undefined,
989
942
  clientId: NonCollabClient,
990
- });
991
- break;
992
- }
943
+ },
944
+ });
945
+ break;
993
946
  }
994
947
 
995
948
  const segInsertOp: ISegment = segment.clone();
@@ -1003,14 +956,9 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1003
956
  }
1004
957
 
1005
958
  case MergeTreeDeltaType.REMOVE: {
1006
- if (
1007
- isRemoved(segment) &&
1008
- segment.localRemovedSeq !== undefined &&
1009
- segment.removedSeq === UnassignedSequenceNumber &&
1010
- (!isMoved(segment) ||
1011
- (segment.localMovedSeq !== undefined &&
1012
- segment.movedSeq === UnassignedSequenceNumber))
1013
- ) {
959
+ // Only bother resubmitting if nobody else has removed it in the meantime.
960
+ // When that happens, the first removal will have been acked.
961
+ if (isRemoved(segment) && opstampUtils.isLocal(segment.removes[0])) {
1014
962
  newOp = createRemoveRangeOp(
1015
963
  segmentPosition,
1016
964
  segmentPosition + segment.cachedLength,
@@ -1020,14 +968,9 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1020
968
  }
1021
969
  case MergeTreeDeltaType.OBLITERATE: {
1022
970
  errorIfOptionNotTrue(this._mergeTree.options, "mergeTreeEnableObliterateReconnect");
1023
- if (
1024
- isMoved(segment) &&
1025
- segment.localMovedSeq !== undefined &&
1026
- segment.movedSeq === UnassignedSequenceNumber &&
1027
- (!isRemoved(segment) ||
1028
- (segment.localRemovedSeq !== undefined &&
1029
- segment.removedSeq === UnassignedSequenceNumber))
1030
- ) {
971
+ // Only bother resubmitting if nobody else has removed it in the meantime.
972
+ // When that happens, the first removal will have been acked.
973
+ if (isRemoved(segment) && opstampUtils.isLocal(segment.removes[0])) {
1031
974
  newOp = createObliterateRangeOp(
1032
975
  segmentPosition,
1033
976
  segmentPosition + segment.cachedLength,
@@ -1219,7 +1162,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1219
1162
  if (Array.isArray(segmentGroup)) {
1220
1163
  if (segmentGroup.length === 0) {
1221
1164
  // sometimes we rebase to an empty op
1222
- // eslint-disable-next-line import/no-deprecated
1165
+
1223
1166
  return createGroupOp();
1224
1167
  }
1225
1168
  firstGroup = segmentGroup[0];
@@ -1274,7 +1217,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1274
1217
  );
1275
1218
  opList.push(...this.resetPendingDeltaToOps(resetOp, segmentGroup));
1276
1219
  }
1277
- // eslint-disable-next-line import/no-deprecated
1220
+
1278
1221
  return opList.length === 1 ? opList[0] : createGroupOp(...opList);
1279
1222
  }
1280
1223
 
@@ -1333,11 +1276,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1333
1276
  return loader.initialize(storage);
1334
1277
  }
1335
1278
 
1336
- private getLocalSequenceNumber(): number {
1337
- const segWindow = this.getCollabWindow();
1338
- return segWindow.collaborating ? UnassignedSequenceNumber : UniversalSequenceNumber;
1339
- }
1340
-
1341
1279
  // eslint-disable-next-line import/no-deprecated
1342
1280
  localTransaction(groupOp: IMergeTreeGroupMsg): void {
1343
1281
  for (const op of groupOp.ops) {
@@ -1382,14 +1320,21 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1382
1320
  segment: T | undefined;
1383
1321
  offset: number | undefined;
1384
1322
  } {
1385
- const { referenceSequenceNumber, clientId } =
1386
- this.getClientSequenceArgsForMessage(sequenceArgs);
1387
- return this._mergeTree.getContainingSegment(
1388
- pos,
1389
- referenceSequenceNumber,
1390
- clientId,
1391
- localSeq,
1392
- ) as {
1323
+ let perspective: Perspective;
1324
+ const clientId =
1325
+ sequenceArgs === undefined
1326
+ ? this.getClientId()
1327
+ : this.getOrAddShortClientIdFromMessage(sequenceArgs);
1328
+ const refSeq = sequenceArgs?.referenceSequenceNumber ?? this.getCollabWindow().currentSeq;
1329
+ if (localSeq !== undefined) {
1330
+ perspective = new LocalReconnectingPerspective(refSeq, clientId, localSeq);
1331
+ } else if (sequenceArgs === undefined) {
1332
+ perspective = this._mergeTree.localPerspective;
1333
+ } else {
1334
+ perspective = new PriorPerspective(refSeq, clientId);
1335
+ }
1336
+
1337
+ return this._mergeTree.getContainingSegment(pos, perspective) as {
1393
1338
  segment: T | undefined;
1394
1339
  offset: number | undefined;
1395
1340
  };
@@ -1472,7 +1417,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
1472
1417
  * @param forwards - Whether the desired marker comes before (false) or after (true) `startPos`
1473
1418
  */
1474
1419
  searchForMarker(startPos: number, markerLabel: string, forwards = true): Marker | undefined {
1475
- const clientId = this.getClientId();
1476
- return this._mergeTree.searchForMarker(startPos, clientId, markerLabel, forwards);
1420
+ return this._mergeTree.searchForMarker(startPos, markerLabel, forwards);
1477
1421
  }
1478
1422
  }