@fluidframework/merge-tree 2.23.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 (323) hide show
  1. package/CHANGELOG.md +407 -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 +38 -22
  20. package/dist/mergeTree.d.ts.map +1 -1
  21. package/dist/mergeTree.js +408 -486
  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 +84 -65
  35. package/dist/perspective.d.ts.map +1 -1
  36. package/dist/perspective.js +109 -108
  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 +90 -0
  59. package/dist/stamps.d.ts.map +1 -0
  60. package/dist/stamps.js +90 -0
  61. package/dist/stamps.js.map +1 -0
  62. package/dist/test/Insertion.perf.spec.js +6 -51
  63. package/dist/test/Insertion.perf.spec.js.map +1 -1
  64. package/dist/test/PartialLengths.perf.spec.js +18 -25
  65. package/dist/test/PartialLengths.perf.spec.js.map +1 -1
  66. package/dist/test/Removal.perf.spec.js +13 -41
  67. package/dist/test/Removal.perf.spec.js.map +1 -1
  68. package/dist/test/beastTest.spec.d.ts.map +1 -1
  69. package/dist/test/beastTest.spec.js +41 -66
  70. package/dist/test/beastTest.spec.js.map +1 -1
  71. package/dist/test/client.annotateMarker.spec.js +1 -11
  72. package/dist/test/client.annotateMarker.spec.js.map +1 -1
  73. package/dist/test/client.applyMsg.spec.js +14 -14
  74. package/dist/test/client.applyMsg.spec.js.map +1 -1
  75. package/dist/test/client.getPosition.spec.js +1 -1
  76. package/dist/test/client.getPosition.spec.js.map +1 -1
  77. package/dist/test/client.localReference.spec.js +1 -1
  78. package/dist/test/client.localReference.spec.js.map +1 -1
  79. package/dist/test/client.rollback.spec.js +49 -58
  80. package/dist/test/client.rollback.spec.js.map +1 -1
  81. package/dist/test/client.rollbackFarm.spec.js +1 -1
  82. package/dist/test/client.rollbackFarm.spec.js.map +1 -1
  83. package/dist/test/client.searchForMarker.spec.js +4 -21
  84. package/dist/test/client.searchForMarker.spec.js.map +1 -1
  85. package/dist/test/index.d.ts +2 -2
  86. package/dist/test/index.d.ts.map +1 -1
  87. package/dist/test/index.js +2 -6
  88. package/dist/test/index.js.map +1 -1
  89. package/dist/test/mergeTree.annotate.deltaCallback.spec.js +14 -59
  90. package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  91. package/dist/test/mergeTree.annotate.spec.js +47 -63
  92. package/dist/test/mergeTree.annotate.spec.js.map +1 -1
  93. package/dist/test/mergeTree.insert.deltaCallback.spec.js +9 -62
  94. package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  95. package/dist/test/mergeTree.insertingWalk.spec.js +59 -125
  96. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
  97. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +12 -93
  98. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  99. package/dist/test/mergeTree.markRangeRemoved.spec.js +10 -7
  100. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  101. package/dist/test/mergeTree.walk.spec.js +2 -14
  102. package/dist/test/mergeTree.walk.spec.js.map +1 -1
  103. package/dist/test/mergeTreeOperationRunner.js +2 -2
  104. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  105. package/dist/test/obliterate.concurrent.spec.js +18 -23
  106. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  107. package/dist/test/obliterate.partialLength.spec.js +166 -136
  108. package/dist/test/obliterate.partialLength.spec.js.map +1 -1
  109. package/dist/test/obliterate.spec.js +16 -126
  110. package/dist/test/obliterate.spec.js.map +1 -1
  111. package/dist/test/partialLength.spec.js +28 -196
  112. package/dist/test/partialLength.spec.js.map +1 -1
  113. package/{prettier.config.cjs → dist/test/perspective.spec.d.ts} +2 -4
  114. package/dist/test/perspective.spec.d.ts.map +1 -0
  115. package/dist/test/perspective.spec.js +153 -0
  116. package/dist/test/perspective.spec.js.map +1 -0
  117. package/dist/test/propertyManager.spec.js +1 -1
  118. package/dist/test/propertyManager.spec.js.map +1 -1
  119. package/dist/test/resetPendingSegmentsToOp.spec.js +0 -2
  120. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  121. package/dist/test/segmentGroupCollection.spec.js +10 -4
  122. package/dist/test/segmentGroupCollection.spec.js.map +1 -1
  123. package/dist/test/stamps.spec.d.ts +6 -0
  124. package/dist/test/stamps.spec.d.ts.map +1 -0
  125. package/dist/test/stamps.spec.js +130 -0
  126. package/dist/test/stamps.spec.js.map +1 -0
  127. package/dist/test/testClient.d.ts +1 -0
  128. package/dist/test/testClient.d.ts.map +1 -1
  129. package/dist/test/testClient.js +16 -26
  130. package/dist/test/testClient.js.map +1 -1
  131. package/dist/test/testClientLogger.d.ts +9 -0
  132. package/dist/test/testClientLogger.d.ts.map +1 -1
  133. package/dist/test/testClientLogger.js +59 -47
  134. package/dist/test/testClientLogger.js.map +1 -1
  135. package/dist/test/testServer.d.ts +2 -1
  136. package/dist/test/testServer.d.ts.map +1 -1
  137. package/dist/test/testServer.js +7 -5
  138. package/dist/test/testServer.js.map +1 -1
  139. package/dist/test/testUtils.d.ts +36 -56
  140. package/dist/test/testUtils.d.ts.map +1 -1
  141. package/dist/test/testUtils.js +68 -77
  142. package/dist/test/testUtils.js.map +1 -1
  143. package/dist/test/text.d.ts +2 -2
  144. package/dist/test/text.d.ts.map +1 -1
  145. package/dist/test/text.js +5 -2
  146. package/dist/test/text.js.map +1 -1
  147. package/dist/textSegment.d.ts +0 -6
  148. package/dist/textSegment.d.ts.map +1 -1
  149. package/dist/textSegment.js.map +1 -1
  150. package/dist/zamboni.d.ts.map +1 -1
  151. package/dist/zamboni.js +53 -26
  152. package/dist/zamboni.js.map +1 -1
  153. package/lib/MergeTreeTextHelper.d.ts +9 -3
  154. package/lib/MergeTreeTextHelper.d.ts.map +1 -1
  155. package/lib/MergeTreeTextHelper.js +5 -5
  156. package/lib/MergeTreeTextHelper.js.map +1 -1
  157. package/lib/client.d.ts +7 -13
  158. package/lib/client.d.ts.map +1 -1
  159. package/lib/client.js +117 -116
  160. package/lib/client.js.map +1 -1
  161. package/lib/endOfTreeSegment.d.ts +12 -8
  162. package/lib/endOfTreeSegment.d.ts.map +1 -1
  163. package/lib/endOfTreeSegment.js +2 -4
  164. package/lib/endOfTreeSegment.js.map +1 -1
  165. package/lib/index.d.ts +6 -3
  166. package/lib/index.d.ts.map +1 -1
  167. package/lib/index.js +1 -1
  168. package/lib/index.js.map +1 -1
  169. package/lib/mergeTree.d.ts +38 -22
  170. package/lib/mergeTree.d.ts.map +1 -1
  171. package/lib/mergeTree.js +389 -491
  172. package/lib/mergeTree.js.map +1 -1
  173. package/lib/mergeTreeDeltaCallback.d.ts +4 -8
  174. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  175. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  176. package/lib/mergeTreeNodes.d.ts +32 -10
  177. package/lib/mergeTreeNodes.d.ts.map +1 -1
  178. package/lib/mergeTreeNodes.js +42 -29
  179. package/lib/mergeTreeNodes.js.map +1 -1
  180. package/lib/partialLengths.d.ts +2 -2
  181. package/lib/partialLengths.d.ts.map +1 -1
  182. package/lib/partialLengths.js +160 -111
  183. package/lib/partialLengths.js.map +1 -1
  184. package/lib/perspective.d.ts +84 -65
  185. package/lib/perspective.d.ts.map +1 -1
  186. package/lib/perspective.js +82 -103
  187. package/lib/perspective.js.map +1 -1
  188. package/lib/revertibles.d.ts.map +1 -1
  189. package/lib/revertibles.js +2 -2
  190. package/lib/revertibles.js.map +1 -1
  191. package/lib/segmentInfos.d.ts +20 -106
  192. package/lib/segmentInfos.d.ts.map +1 -1
  193. package/lib/segmentInfos.js +26 -37
  194. package/lib/segmentInfos.js.map +1 -1
  195. package/lib/segmentPropertiesManager.d.ts +1 -14
  196. package/lib/segmentPropertiesManager.d.ts.map +1 -1
  197. package/lib/segmentPropertiesManager.js +2 -16
  198. package/lib/segmentPropertiesManager.js.map +1 -1
  199. package/lib/snapshotLoader.d.ts.map +1 -1
  200. package/lib/snapshotLoader.js +39 -19
  201. package/lib/snapshotLoader.js.map +1 -1
  202. package/lib/snapshotV1.d.ts.map +1 -1
  203. package/lib/snapshotV1.js +34 -26
  204. package/lib/snapshotV1.js.map +1 -1
  205. package/lib/snapshotlegacy.d.ts.map +1 -1
  206. package/lib/snapshotlegacy.js +7 -10
  207. package/lib/snapshotlegacy.js.map +1 -1
  208. package/lib/stamps.d.ts +90 -0
  209. package/lib/stamps.d.ts.map +1 -0
  210. package/lib/stamps.js +77 -0
  211. package/lib/stamps.js.map +1 -0
  212. package/lib/test/Insertion.perf.spec.js +6 -51
  213. package/lib/test/Insertion.perf.spec.js.map +1 -1
  214. package/lib/test/PartialLengths.perf.spec.js +18 -25
  215. package/lib/test/PartialLengths.perf.spec.js.map +1 -1
  216. package/lib/test/Removal.perf.spec.js +13 -41
  217. package/lib/test/Removal.perf.spec.js.map +1 -1
  218. package/lib/test/beastTest.spec.d.ts.map +1 -1
  219. package/lib/test/beastTest.spec.js +42 -67
  220. package/lib/test/beastTest.spec.js.map +1 -1
  221. package/lib/test/client.annotateMarker.spec.js +1 -11
  222. package/lib/test/client.annotateMarker.spec.js.map +1 -1
  223. package/lib/test/client.applyMsg.spec.js +14 -14
  224. package/lib/test/client.applyMsg.spec.js.map +1 -1
  225. package/lib/test/client.getPosition.spec.js +1 -1
  226. package/lib/test/client.getPosition.spec.js.map +1 -1
  227. package/lib/test/client.localReference.spec.js +1 -1
  228. package/lib/test/client.localReference.spec.js.map +1 -1
  229. package/lib/test/client.rollback.spec.js +50 -59
  230. package/lib/test/client.rollback.spec.js.map +1 -1
  231. package/lib/test/client.rollbackFarm.spec.js +1 -1
  232. package/lib/test/client.rollbackFarm.spec.js.map +1 -1
  233. package/lib/test/client.searchForMarker.spec.js +4 -21
  234. package/lib/test/client.searchForMarker.spec.js.map +1 -1
  235. package/lib/test/index.d.ts +2 -2
  236. package/lib/test/index.d.ts.map +1 -1
  237. package/lib/test/index.js +1 -1
  238. package/lib/test/index.js.map +1 -1
  239. package/lib/test/mergeTree.annotate.deltaCallback.spec.js +15 -60
  240. package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  241. package/lib/test/mergeTree.annotate.spec.js +48 -64
  242. package/lib/test/mergeTree.annotate.spec.js.map +1 -1
  243. package/lib/test/mergeTree.insert.deltaCallback.spec.js +10 -63
  244. package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  245. package/lib/test/mergeTree.insertingWalk.spec.js +61 -127
  246. package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
  247. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +13 -94
  248. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  249. package/lib/test/mergeTree.markRangeRemoved.spec.js +10 -7
  250. package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  251. package/lib/test/mergeTree.walk.spec.js +2 -14
  252. package/lib/test/mergeTree.walk.spec.js.map +1 -1
  253. package/lib/test/mergeTreeOperationRunner.js +3 -3
  254. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  255. package/lib/test/obliterate.concurrent.spec.js +18 -23
  256. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  257. package/lib/test/obliterate.partialLength.spec.js +167 -137
  258. package/lib/test/obliterate.partialLength.spec.js.map +1 -1
  259. package/lib/test/obliterate.spec.js +17 -127
  260. package/lib/test/obliterate.spec.js.map +1 -1
  261. package/lib/test/partialLength.spec.js +29 -197
  262. package/lib/test/partialLength.spec.js.map +1 -1
  263. package/lib/test/perspective.spec.d.ts +6 -0
  264. package/lib/test/perspective.spec.d.ts.map +1 -0
  265. package/lib/test/perspective.spec.js +151 -0
  266. package/lib/test/perspective.spec.js.map +1 -0
  267. package/lib/test/propertyManager.spec.js +2 -2
  268. package/lib/test/propertyManager.spec.js.map +1 -1
  269. package/lib/test/resetPendingSegmentsToOp.spec.js +0 -2
  270. package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  271. package/lib/test/segmentGroupCollection.spec.js +10 -4
  272. package/lib/test/segmentGroupCollection.spec.js.map +1 -1
  273. package/lib/test/stamps.spec.d.ts +6 -0
  274. package/lib/test/stamps.spec.d.ts.map +1 -0
  275. package/lib/test/stamps.spec.js +105 -0
  276. package/lib/test/stamps.spec.js.map +1 -0
  277. package/lib/test/testClient.d.ts +1 -0
  278. package/lib/test/testClient.d.ts.map +1 -1
  279. package/lib/test/testClient.js +18 -28
  280. package/lib/test/testClient.js.map +1 -1
  281. package/lib/test/testClientLogger.d.ts +9 -0
  282. package/lib/test/testClientLogger.d.ts.map +1 -1
  283. package/lib/test/testClientLogger.js +60 -48
  284. package/lib/test/testClientLogger.js.map +1 -1
  285. package/lib/test/testServer.d.ts +2 -1
  286. package/lib/test/testServer.d.ts.map +1 -1
  287. package/lib/test/testServer.js +7 -5
  288. package/lib/test/testServer.js.map +1 -1
  289. package/lib/test/testUtils.d.ts +36 -56
  290. package/lib/test/testUtils.d.ts.map +1 -1
  291. package/lib/test/testUtils.js +66 -48
  292. package/lib/test/testUtils.js.map +1 -1
  293. package/lib/test/text.d.ts +2 -2
  294. package/lib/test/text.d.ts.map +1 -1
  295. package/lib/test/text.js +6 -3
  296. package/lib/test/text.js.map +1 -1
  297. package/lib/textSegment.d.ts +0 -6
  298. package/lib/textSegment.d.ts.map +1 -1
  299. package/lib/textSegment.js.map +1 -1
  300. package/lib/tsdoc-metadata.json +1 -1
  301. package/lib/zamboni.d.ts.map +1 -1
  302. package/lib/zamboni.js +32 -28
  303. package/lib/zamboni.js.map +1 -1
  304. package/package.json +18 -21
  305. package/src/MergeTreeTextHelper.ts +17 -12
  306. package/src/client.ts +141 -197
  307. package/src/endOfTreeSegment.ts +11 -8
  308. package/src/index.ts +4 -3
  309. package/src/mergeTree.ts +501 -631
  310. package/src/mergeTreeDeltaCallback.ts +4 -8
  311. package/src/mergeTreeNodes.ts +66 -45
  312. package/src/partialLengths.ts +181 -137
  313. package/src/perspective.ts +127 -129
  314. package/src/revertibles.ts +2 -7
  315. package/src/segmentInfos.ts +48 -141
  316. package/src/segmentPropertiesManager.ts +2 -16
  317. package/src/snapshotLoader.ts +62 -30
  318. package/src/snapshotV1.ts +36 -28
  319. package/src/snapshotlegacy.ts +7 -16
  320. package/src/stamps.ts +164 -0
  321. package/src/textSegment.ts +0 -13
  322. package/src/zamboni.ts +38 -32
  323. package/tsconfig.json +1 -0
@@ -0,0 +1,151 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { strict as assert } from "node:assert";
6
+ import { UnassignedSequenceNumber } from "../constants.js";
7
+ import { LocalDefaultPerspective, LocalReconnectingPerspective, PriorPerspective, RemoteObliteratePerspective, } from "../perspective.js";
8
+ const clientId = 17;
9
+ describe("PriorPerspective", () => {
10
+ const refSeq = 10;
11
+ const perspective = new PriorPerspective(refSeq, clientId);
12
+ it("sees operations from the same client", () => {
13
+ const stamp = { clientId, seq: 1 };
14
+ assert.ok(perspective.hasOccurred(stamp));
15
+ });
16
+ it("sees operations at or below the refSeq", () => {
17
+ for (let seq = 0; seq <= refSeq; seq++) {
18
+ const stamp = { clientId, seq };
19
+ assert.ok(perspective.hasOccurred(stamp), `Failed for seq ${seq}`);
20
+ }
21
+ });
22
+ it("Does not see operations from other clients above the refSeq", () => {
23
+ const stamp = { clientId: clientId + 1, seq: refSeq + 1 };
24
+ assert.ok(!perspective.hasOccurred(stamp));
25
+ });
26
+ it("Uses operations to determine segment visibility", () => {
27
+ const insert = { type: "insert", seq: 5, clientId };
28
+ const remove1 = { type: "setRemove", seq: 10, clientId };
29
+ const remove2 = { type: "sliceRemove", seq: 12, clientId };
30
+ const seg1 = { insert };
31
+ const seg2 = { insert, removes: [remove1] };
32
+ const seg3 = {
33
+ insert,
34
+ removes: [remove1, remove2],
35
+ };
36
+ const seg4 = {
37
+ insert,
38
+ removes: [remove2],
39
+ };
40
+ const perspective1 = new PriorPerspective(4, clientId + 1);
41
+ const perspective2 = new PriorPerspective(6, clientId + 1);
42
+ const perspective3 = new PriorPerspective(10, clientId + 1);
43
+ // Only perspectives 2 and 3 have seen the insert
44
+ assert.ok(!perspective1.isSegmentPresent(seg1));
45
+ assert.ok(perspective2.isSegmentPresent(seg1));
46
+ assert.ok(perspective3.isSegmentPresent(seg1));
47
+ // Perspectives 2 and 3 have seen the insert, and perspective 3 has seen the remove
48
+ assert.ok(!perspective1.isSegmentPresent(seg2));
49
+ assert.ok(perspective2.isSegmentPresent(seg2));
50
+ assert.ok(!perspective3.isSegmentPresent(seg2));
51
+ // Perspectives 2 and 3 have seen the insert, and perspective 3 has seen one of the removes
52
+ assert.ok(!perspective1.isSegmentPresent(seg3));
53
+ assert.ok(perspective2.isSegmentPresent(seg3));
54
+ assert.ok(!perspective3.isSegmentPresent(seg3));
55
+ // Perspectives 2 and 3 have seen the insert, and none have seen the remove
56
+ assert.ok(!perspective1.isSegmentPresent(seg4));
57
+ assert.ok(perspective2.isSegmentPresent(seg4));
58
+ assert.ok(perspective3.isSegmentPresent(seg4));
59
+ });
60
+ });
61
+ describe("LocalReconnectingPerspective", () => {
62
+ const refSeq = 10;
63
+ const localSeq = 20;
64
+ const perspective = new LocalReconnectingPerspective(refSeq, clientId, localSeq);
65
+ it("sees operations from the same client at or below localSeq", () => {
66
+ for (let i = 0; i <= localSeq; i++) {
67
+ const stamp = { seq: UnassignedSequenceNumber, clientId, localSeq: i };
68
+ assert.ok(perspective.hasOccurred(stamp), `Failed for localSeq ${i}`);
69
+ }
70
+ });
71
+ it("does not see operations from the same client above localSeq", () => {
72
+ const stamp = {
73
+ seq: UnassignedSequenceNumber,
74
+ clientId,
75
+ localSeq: localSeq + 1,
76
+ };
77
+ assert.ok(!perspective.hasOccurred(stamp));
78
+ });
79
+ it("sees operations at or below refSeq", () => {
80
+ for (let seq = 0; seq <= refSeq; seq++) {
81
+ const stamp = {
82
+ seq,
83
+ clientId: seq % 3 === 0 ? clientId : clientId + 1,
84
+ };
85
+ assert.ok(perspective.hasOccurred(stamp), `Failed for seq ${seq}`);
86
+ }
87
+ });
88
+ it("does not see operations from other clients above refSeq", () => {
89
+ const stamp = { seq: refSeq + 1, clientId: clientId + 1 };
90
+ assert.ok(!perspective.hasOccurred(stamp));
91
+ });
92
+ });
93
+ describe("LocalDefaultPerspective", () => {
94
+ const perspective = new LocalDefaultPerspective(clientId);
95
+ it("sees all operations", () => {
96
+ for (const id of [0, 1, 2, 3, clientId]) {
97
+ for (const refSeq of [0, 1, 5, 100, 1000]) {
98
+ const stamp = { seq: 1, clientId: id };
99
+ assert.ok(perspective.hasOccurred(stamp), `Failed for clientId ${id} and refSeq ${refSeq}`);
100
+ }
101
+ }
102
+ for (const localSeq of [0, 1, 5, 100, 1000]) {
103
+ const stamp = { seq: UnassignedSequenceNumber, clientId, localSeq };
104
+ assert.ok(perspective.hasOccurred(stamp), `Failed for localSeq ${localSeq}`);
105
+ }
106
+ });
107
+ });
108
+ describe("RemoteObliteratePerspective", () => {
109
+ const perspective = new RemoteObliteratePerspective(clientId);
110
+ it("Sees all inserts", () => {
111
+ for (const id of [0, 1, 2, 3, clientId]) {
112
+ for (const refSeq of [0, 1, 5, 100, 1000]) {
113
+ const stamp = { type: "insert", seq: 1, clientId: id };
114
+ assert.ok(perspective.hasOccurred(stamp), `Failed for clientId ${id} and refSeq ${refSeq}`);
115
+ }
116
+ }
117
+ for (const localSeq of [0, 1, 5, 100, 1000]) {
118
+ const stamp = {
119
+ type: "insert",
120
+ seq: UnassignedSequenceNumber,
121
+ clientId,
122
+ localSeq,
123
+ };
124
+ assert.ok(perspective.hasOccurred(stamp), `Failed for localSeq ${localSeq}`);
125
+ }
126
+ });
127
+ it("Sees remote removes", () => {
128
+ for (const id of [0, 1, 2, 3, clientId]) {
129
+ for (const refSeq of [0, 1, 5, 100, 1000]) {
130
+ for (const type of ["setRemove", "sliceRemove"]) {
131
+ const stamp = { type, seq: 1, clientId: id };
132
+ assert.ok(perspective.hasOccurred(stamp), `Failed for clientId ${id} and refSeq ${refSeq} with ${type}`);
133
+ }
134
+ }
135
+ }
136
+ });
137
+ it("Does not see local removes", () => {
138
+ for (const localSeq of [0, 1, 5, 100, 1000]) {
139
+ for (const type of ["setRemove", "sliceRemove"]) {
140
+ const stamp = {
141
+ type,
142
+ seq: UnassignedSequenceNumber,
143
+ clientId,
144
+ localSeq,
145
+ };
146
+ assert.ok(!perspective.hasOccurred(stamp), `Failed for localSeq ${localSeq}`);
147
+ }
148
+ }
149
+ });
150
+ });
151
+ //# sourceMappingURL=perspective.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perspective.spec.js","sourceRoot":"","sources":["../../src/test/perspective.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport type { ISegmentLeaf } from \"../mergeTreeNodes.js\";\nimport {\n\tLocalDefaultPerspective,\n\tLocalReconnectingPerspective,\n\tPriorPerspective,\n\tRemoteObliteratePerspective,\n} from \"../perspective.js\";\nimport type { IHasInsertionInfo, IHasRemovalInfo } from \"../segmentInfos.js\";\nimport type { InsertOperationStamp, OperationStamp, RemoveOperationStamp } from \"../stamps.js\";\n\nconst clientId = 17;\ndescribe(\"PriorPerspective\", () => {\n\tconst refSeq = 10;\n\tconst perspective = new PriorPerspective(refSeq, clientId);\n\tit(\"sees operations from the same client\", () => {\n\t\tconst stamp: OperationStamp = { clientId, seq: 1 };\n\t\tassert.ok(perspective.hasOccurred(stamp));\n\t});\n\n\tit(\"sees operations at or below the refSeq\", () => {\n\t\tfor (let seq = 0; seq <= refSeq; seq++) {\n\t\t\tconst stamp: OperationStamp = { clientId, seq };\n\t\t\tassert.ok(perspective.hasOccurred(stamp), `Failed for seq ${seq}`);\n\t\t}\n\t});\n\n\tit(\"Does not see operations from other clients above the refSeq\", () => {\n\t\tconst stamp: OperationStamp = { clientId: clientId + 1, seq: refSeq + 1 };\n\t\tassert.ok(!perspective.hasOccurred(stamp));\n\t});\n\n\tit(\"Uses operations to determine segment visibility\", () => {\n\t\tconst insert: InsertOperationStamp = { type: \"insert\", seq: 5, clientId };\n\t\tconst remove1: RemoveOperationStamp = { type: \"setRemove\", seq: 10, clientId };\n\t\tconst remove2: RemoveOperationStamp = { type: \"sliceRemove\", seq: 12, clientId };\n\t\tconst seg1 = { insert } satisfies IHasInsertionInfo as unknown as ISegmentLeaf;\n\t\tconst seg2: ISegmentLeaf = { insert, removes: [remove1] } satisfies IHasInsertionInfo &\n\t\t\tIHasRemovalInfo as unknown as ISegmentLeaf;\n\t\tconst seg3 = {\n\t\t\tinsert,\n\t\t\tremoves: [remove1, remove2],\n\t\t} satisfies IHasInsertionInfo & IHasRemovalInfo as unknown as ISegmentLeaf;\n\t\tconst seg4 = {\n\t\t\tinsert,\n\t\t\tremoves: [remove2],\n\t\t} satisfies IHasInsertionInfo & IHasRemovalInfo as unknown as ISegmentLeaf;\n\t\tconst perspective1 = new PriorPerspective(4, clientId + 1);\n\t\tconst perspective2 = new PriorPerspective(6, clientId + 1);\n\t\tconst perspective3 = new PriorPerspective(10, clientId + 1);\n\n\t\t// Only perspectives 2 and 3 have seen the insert\n\t\tassert.ok(!perspective1.isSegmentPresent(seg1));\n\t\tassert.ok(perspective2.isSegmentPresent(seg1));\n\t\tassert.ok(perspective3.isSegmentPresent(seg1));\n\n\t\t// Perspectives 2 and 3 have seen the insert, and perspective 3 has seen the remove\n\t\tassert.ok(!perspective1.isSegmentPresent(seg2));\n\t\tassert.ok(perspective2.isSegmentPresent(seg2));\n\t\tassert.ok(!perspective3.isSegmentPresent(seg2));\n\n\t\t// Perspectives 2 and 3 have seen the insert, and perspective 3 has seen one of the removes\n\t\tassert.ok(!perspective1.isSegmentPresent(seg3));\n\t\tassert.ok(perspective2.isSegmentPresent(seg3));\n\t\tassert.ok(!perspective3.isSegmentPresent(seg3));\n\n\t\t// Perspectives 2 and 3 have seen the insert, and none have seen the remove\n\t\tassert.ok(!perspective1.isSegmentPresent(seg4));\n\t\tassert.ok(perspective2.isSegmentPresent(seg4));\n\t\tassert.ok(perspective3.isSegmentPresent(seg4));\n\t});\n});\n\ndescribe(\"LocalReconnectingPerspective\", () => {\n\tconst refSeq = 10;\n\tconst localSeq = 20;\n\tconst perspective = new LocalReconnectingPerspective(refSeq, clientId, localSeq);\n\tit(\"sees operations from the same client at or below localSeq\", () => {\n\t\tfor (let i = 0; i <= localSeq; i++) {\n\t\t\tconst stamp: OperationStamp = { seq: UnassignedSequenceNumber, clientId, localSeq: i };\n\t\t\tassert.ok(perspective.hasOccurred(stamp), `Failed for localSeq ${i}`);\n\t\t}\n\t});\n\n\tit(\"does not see operations from the same client above localSeq\", () => {\n\t\tconst stamp: OperationStamp = {\n\t\t\tseq: UnassignedSequenceNumber,\n\t\t\tclientId,\n\t\t\tlocalSeq: localSeq + 1,\n\t\t};\n\t\tassert.ok(!perspective.hasOccurred(stamp));\n\t});\n\n\tit(\"sees operations at or below refSeq\", () => {\n\t\tfor (let seq = 0; seq <= refSeq; seq++) {\n\t\t\tconst stamp: OperationStamp = {\n\t\t\t\tseq,\n\t\t\t\tclientId: seq % 3 === 0 ? clientId : clientId + 1,\n\t\t\t};\n\t\t\tassert.ok(perspective.hasOccurred(stamp), `Failed for seq ${seq}`);\n\t\t}\n\t});\n\n\tit(\"does not see operations from other clients above refSeq\", () => {\n\t\tconst stamp: OperationStamp = { seq: refSeq + 1, clientId: clientId + 1 };\n\t\tassert.ok(!perspective.hasOccurred(stamp));\n\t});\n});\n\ndescribe(\"LocalDefaultPerspective\", () => {\n\tconst perspective = new LocalDefaultPerspective(clientId);\n\tit(\"sees all operations\", () => {\n\t\tfor (const id of [0, 1, 2, 3, clientId]) {\n\t\t\tfor (const refSeq of [0, 1, 5, 100, 1000]) {\n\t\t\t\tconst stamp: OperationStamp = { seq: 1, clientId: id };\n\t\t\t\tassert.ok(\n\t\t\t\t\tperspective.hasOccurred(stamp),\n\t\t\t\t\t`Failed for clientId ${id} and refSeq ${refSeq}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tfor (const localSeq of [0, 1, 5, 100, 1000]) {\n\t\t\tconst stamp: OperationStamp = { seq: UnassignedSequenceNumber, clientId, localSeq };\n\t\t\tassert.ok(perspective.hasOccurred(stamp), `Failed for localSeq ${localSeq}`);\n\t\t}\n\t});\n});\n\ndescribe(\"RemoteObliteratePerspective\", () => {\n\tconst perspective = new RemoteObliteratePerspective(clientId);\n\tit(\"Sees all inserts\", () => {\n\t\tfor (const id of [0, 1, 2, 3, clientId]) {\n\t\t\tfor (const refSeq of [0, 1, 5, 100, 1000]) {\n\t\t\t\tconst stamp: InsertOperationStamp = { type: \"insert\", seq: 1, clientId: id };\n\t\t\t\tassert.ok(\n\t\t\t\t\tperspective.hasOccurred(stamp),\n\t\t\t\t\t`Failed for clientId ${id} and refSeq ${refSeq}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tfor (const localSeq of [0, 1, 5, 100, 1000]) {\n\t\t\tconst stamp: InsertOperationStamp = {\n\t\t\t\ttype: \"insert\",\n\t\t\t\tseq: UnassignedSequenceNumber,\n\t\t\t\tclientId,\n\t\t\t\tlocalSeq,\n\t\t\t};\n\t\t\tassert.ok(perspective.hasOccurred(stamp), `Failed for localSeq ${localSeq}`);\n\t\t}\n\t});\n\n\tit(\"Sees remote removes\", () => {\n\t\tfor (const id of [0, 1, 2, 3, clientId]) {\n\t\t\tfor (const refSeq of [0, 1, 5, 100, 1000]) {\n\t\t\t\tfor (const type of [\"setRemove\", \"sliceRemove\"] as const) {\n\t\t\t\t\tconst stamp: RemoveOperationStamp = { type, seq: 1, clientId: id };\n\t\t\t\t\tassert.ok(\n\t\t\t\t\t\tperspective.hasOccurred(stamp),\n\t\t\t\t\t\t`Failed for clientId ${id} and refSeq ${refSeq} with ${type}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\tit(\"Does not see local removes\", () => {\n\t\tfor (const localSeq of [0, 1, 5, 100, 1000]) {\n\t\t\tfor (const type of [\"setRemove\", \"sliceRemove\"] as const) {\n\t\t\t\tconst stamp: RemoveOperationStamp = {\n\t\t\t\t\ttype,\n\t\t\t\t\tseq: UnassignedSequenceNumber,\n\t\t\t\t\tclientId,\n\t\t\t\t\tlocalSeq,\n\t\t\t\t};\n\t\t\t\tassert.ok(!perspective.hasOccurred(stamp), `Failed for localSeq ${localSeq}`);\n\t\t\t}\n\t\t}\n\t});\n});\n"]}
@@ -5,7 +5,7 @@
5
5
  import { strict as assert } from "node:assert";
6
6
  import { UnassignedSequenceNumber } from "../constants.js";
7
7
  import { matchProperties } from "../properties.js";
8
- import { PropertiesManager, PropertiesRollback, } from "../segmentPropertiesManager.js";
8
+ import { PropertiesManager } from "../segmentPropertiesManager.js";
9
9
  describe("PropertiesManager", () => {
10
10
  describe("handleProperties", () => {
11
11
  it("should handle properties without collaboration", () => {
@@ -36,7 +36,7 @@ describe("PropertiesManager", () => {
36
36
  const op = { props: { key: "newValue" } };
37
37
  // Simulate pending state for rollback
38
38
  propertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 0, true);
39
- const deltas = propertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 0, true, PropertiesRollback.Rollback);
39
+ const deltas = propertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 0, true, true);
40
40
  assert.deepEqual(deltas, { key: "newValue" });
41
41
  assert.deepEqual(seg.properties, { key: "value" });
42
42
  });
@@ -1 +1 @@
1
- {"version":3,"file":"propertyManager.spec.js","sourceRoot":"","sources":["../../src/test/propertyManager.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport type { ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { matchProperties } from \"../properties.js\";\nimport {\n\tPropertiesManager,\n\tPropertiesRollback,\n\ttype PropsOrAdjust,\n} from \"../segmentPropertiesManager.js\";\n\ndescribe(\"PropertiesManager\", () => {\n\tdescribe(\"handleProperties\", () => {\n\t\tit(\"should handle properties without collaboration\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 1, 0, false);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with collaboration\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with rollback\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\t// Simulate pending state for rollback\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 0, true);\n\t\t\tconst deltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t\tPropertiesRollback.Rollback,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"newValue\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"value\" });\n\t\t});\n\n\t\tit(\"should handle properties with seq as a number and collaborating true\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 2, 1, true);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with seq as a number and collaborating false\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 2, 1, false);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with adjusts\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: 1 },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { adjust: { key: { delta: 1 } } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 2, 1, true);\n\t\t\tassert.deepEqual(deltas, { key: 1 });\n\t\t\tassert.deepEqual(seg.properties, { key: 2 });\n\t\t});\n\n\t\tit(\"should handle properties with props and adjusts interleaved\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: 1, otherKey: \"value\" },\n\t\t\t};\n\t\t\tconst op1: PropsOrAdjust = { props: { otherKey: \"newValue\" } };\n\t\t\tconst op2: PropsOrAdjust = { adjust: { key: { delta: 1 } } };\n\t\t\tpropertiesManager.handleProperties(op1, seg, 2, 1, true);\n\t\t\tconst deltas = propertiesManager.handleProperties(op2, seg, 3, 2, true);\n\t\t\tassert.deepEqual(deltas, { key: 1 });\n\t\t\tassert.deepEqual(seg.properties, { key: 2, otherKey: \"newValue\" });\n\t\t});\n\t});\n\n\tdescribe(\"rollbackProperties\", () => {\n\t\tit(\"should rollback properties when collaborating is true\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst rollbackDeltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tconst deltas = propertiesManager.rollbackProperties(\n\t\t\t\t{ props: rollbackDeltas },\n\t\t\t\tseg,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"newValue\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"value\" });\n\t\t});\n\n\t\tit(\"should rollback properties when collaborating is false\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst rollbackDeltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\tconst deltas = propertiesManager.rollbackProperties(\n\t\t\t\t{ props: rollbackDeltas },\n\t\t\t\tseg,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"newValue\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"value\" });\n\t\t});\n\t});\n\n\tdescribe(\"ack\", () => {\n\t\tit(\"should acknowledge property changes\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"value\" } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 1, true);\n\t\t\tassert(propertiesManager.hasPendingProperties({ key: \"value\" }));\n\t\t\tpropertiesManager.ack(1, 0, op);\n\t\t});\n\t});\n\n\tdescribe(\"copyTo\", () => {\n\t\tit(\"should copy properties and manager state\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"value\" } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 1, true);\n\t\t\tassert(propertiesManager.hasPendingProperties({ key: \"value\" }));\n\t\t\tconst dest: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {};\n\t\t\tpropertiesManager.copyTo({ key: \"value\" }, dest);\n\t\t\tassert(dest.propertyManager instanceof PropertiesManager);\n\t\t\tassert(dest.propertyManager.hasPendingProperties({ key: \"value\" }));\n\t\t});\n\t});\n\n\tdescribe(\"getAtSeq\", () => {\n\t\tit(\"should retrieve properties at a specific sequence number\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { adjust: { key: { delta: 5 } } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, 1, 0, true);\n\t\t\tconst properties = propertiesManager.getAtSeq(seg.properties, 0);\n\t\t\tassert(matchProperties(properties, {}));\n\t\t});\n\t});\n\n\tdescribe(\"hasPendingProperties\", () => {\n\t\tit(\"should check for pending properties\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"value\" } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 1, true);\n\t\t\tassert(propertiesManager.hasPendingProperties({ key: \"value\" }));\n\t\t\tassert(!propertiesManager.hasPendingProperties({ otherKey: \"otherValue\" }));\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"propertyManager.spec.js","sourceRoot":"","sources":["../../src/test/propertyManager.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport type { ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { matchProperties } from \"../properties.js\";\nimport { PropertiesManager, type PropsOrAdjust } from \"../segmentPropertiesManager.js\";\n\ndescribe(\"PropertiesManager\", () => {\n\tdescribe(\"handleProperties\", () => {\n\t\tit(\"should handle properties without collaboration\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 1, 0, false);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with collaboration\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with rollback\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\t// Simulate pending state for rollback\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 0, true);\n\t\t\tconst deltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"newValue\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"value\" });\n\t\t});\n\n\t\tit(\"should handle properties with seq as a number and collaborating true\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 2, 1, true);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with seq as a number and collaborating false\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 2, 1, false);\n\t\t\tassert.deepEqual(deltas, { key: \"value\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"newValue\" });\n\t\t});\n\n\t\tit(\"should handle properties with adjusts\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: 1 },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { adjust: { key: { delta: 1 } } };\n\t\t\tconst deltas = propertiesManager.handleProperties(op, seg, 2, 1, true);\n\t\t\tassert.deepEqual(deltas, { key: 1 });\n\t\t\tassert.deepEqual(seg.properties, { key: 2 });\n\t\t});\n\n\t\tit(\"should handle properties with props and adjusts interleaved\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: 1, otherKey: \"value\" },\n\t\t\t};\n\t\t\tconst op1: PropsOrAdjust = { props: { otherKey: \"newValue\" } };\n\t\t\tconst op2: PropsOrAdjust = { adjust: { key: { delta: 1 } } };\n\t\t\tpropertiesManager.handleProperties(op1, seg, 2, 1, true);\n\t\t\tconst deltas = propertiesManager.handleProperties(op2, seg, 3, 2, true);\n\t\t\tassert.deepEqual(deltas, { key: 1 });\n\t\t\tassert.deepEqual(seg.properties, { key: 2, otherKey: \"newValue\" });\n\t\t});\n\t});\n\n\tdescribe(\"rollbackProperties\", () => {\n\t\tit(\"should rollback properties when collaborating is true\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst rollbackDeltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tconst deltas = propertiesManager.rollbackProperties(\n\t\t\t\t{ props: rollbackDeltas },\n\t\t\t\tseg,\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"newValue\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"value\" });\n\t\t});\n\n\t\tit(\"should rollback properties when collaborating is false\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {\n\t\t\t\tproperties: { key: \"value\" },\n\t\t\t};\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"newValue\" } };\n\t\t\tconst rollbackDeltas = propertiesManager.handleProperties(\n\t\t\t\top,\n\t\t\t\tseg,\n\t\t\t\tUnassignedSequenceNumber,\n\t\t\t\t0,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\tconst deltas = propertiesManager.rollbackProperties(\n\t\t\t\t{ props: rollbackDeltas },\n\t\t\t\tseg,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\tassert.deepEqual(deltas, { key: \"newValue\" });\n\t\t\tassert.deepEqual(seg.properties, { key: \"value\" });\n\t\t});\n\t});\n\n\tdescribe(\"ack\", () => {\n\t\tit(\"should acknowledge property changes\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"value\" } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 1, true);\n\t\t\tassert(propertiesManager.hasPendingProperties({ key: \"value\" }));\n\t\t\tpropertiesManager.ack(1, 0, op);\n\t\t});\n\t});\n\n\tdescribe(\"copyTo\", () => {\n\t\tit(\"should copy properties and manager state\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"value\" } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 1, true);\n\t\t\tassert(propertiesManager.hasPendingProperties({ key: \"value\" }));\n\t\t\tconst dest: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = {};\n\t\t\tpropertiesManager.copyTo({ key: \"value\" }, dest);\n\t\t\tassert(dest.propertyManager instanceof PropertiesManager);\n\t\t\tassert(dest.propertyManager.hasPendingProperties({ key: \"value\" }));\n\t\t});\n\t});\n\n\tdescribe(\"getAtSeq\", () => {\n\t\tit(\"should retrieve properties at a specific sequence number\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { adjust: { key: { delta: 5 } } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, 1, 0, true);\n\t\t\tconst properties = propertiesManager.getAtSeq(seg.properties, 0);\n\t\t\tassert(matchProperties(properties, {}));\n\t\t});\n\t});\n\n\tdescribe(\"hasPendingProperties\", () => {\n\t\tit(\"should check for pending properties\", () => {\n\t\t\tconst propertiesManager = new PropertiesManager();\n\t\t\tconst op: PropsOrAdjust = { props: { key: \"value\" } };\n\t\t\tconst seg: Pick<ISegmentPrivate, \"properties\" | \"propertyManager\"> = { properties: {} };\n\n\t\t\tpropertiesManager.handleProperties(op, seg, UnassignedSequenceNumber, 1, true);\n\t\t\tassert(propertiesManager.hasPendingProperties({ key: \"value\" }));\n\t\t\tassert(!propertiesManager.hasPendingProperties({ otherKey: \"otherValue\" }));\n\t\t});\n\t});\n});\n"]}
@@ -107,7 +107,6 @@ describe("resetPendingSegmentsToOp", () => {
107
107
  op: client.removeRangeLocal(0, client.getLength()),
108
108
  refSeq: client.getCurrentSeq(),
109
109
  });
110
- // eslint-disable-next-line unicorn/no-array-push-push
111
110
  opList.push({
112
111
  op: client.regeneratePendingOp(opList.shift().op, client.mergeTree.pendingSegments.first.data),
113
112
  refSeq: client.getCurrentSeq(),
@@ -151,7 +150,6 @@ describe("resetPendingSegmentsToOp", () => {
151
150
  op: client.annotateRangeLocal(0, client.getLength(), { foo: "bar" }),
152
151
  refSeq: client.getCurrentSeq(),
153
152
  });
154
- // eslint-disable-next-line unicorn/no-array-push-push
155
153
  opList.push({
156
154
  op: client.regeneratePendingOp(opList.shift().op, client.mergeTree.pendingSegments.first.data),
157
155
  refSeq: client.getCurrentSeq(),
@@ -1 +1 @@
1
- {"version":3,"file":"resetPendingSegmentsToOp.spec.js","sourceRoot":"","sources":["../../src/test/resetPendingSegmentsToOp.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6DAA6D;AAE7D,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAI/C,OAAO,EACN,MAAM,EAEN,mBAAmB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAgB,aAAa,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAEtF,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACzC,IAAI,MAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC1B,MAAM,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAChD,MAAM,WAAW,GAAG,CAAC,CAAC;QACtB,MAAM,oBAAoB,GAAG,WAAW,GAAG,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,MAA8C,CAAC;QACnD,IAAI,OAAO,GAAW,CAAC,CAAC;QAExB,SAAS,WAAW,CAAC,GAAe;YACnC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,EAAE,EAAE,CAAC;oBACR,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;oBAC7D,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC;YACF,CAAC;QACF,CAAC;QAED,UAAU,CAAC,GAAG,EAAE;YACf,MAAM,GAAG,EAAE,CAAC;YACZ,OAAO,GAAG,CAAC,CAAC;YAEZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,OAAO,CAAE,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;gBACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/D,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACpC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YACjD,+DAA+D;YAC/D,sGAAsG;YACtG,wGAAwG;YACxG,8DAA8D;YAC9D,qGAAqG;YACrG,oCAAoC;YACpC,IAAI,yBAAyB,GAAG,CAAC,CAAC;YAClC,MAAM,cAAc,GAAG,MAAM,CAAC,SAG7B,CAAC;YACF,cAAc,CAAC,sBAAsB,GAAG,cAAc,CAAC,qBAAqB,CAAC;YAC7E,MAAM,CAAC,cAAc,CACpB,MAAM,CAAC,SAA0D,EACjE,uBAAuB,EACvB;gBACC,GAAG;oBACF,sEAAsE;oBACtE,OAAO,IAAI,CAAC,sBAAiC,CAAC;gBAC/C,CAAC;gBACD,GAAG,CAAC,QAAQ;oBACX,IAAI,QAAQ,EAAE,CAAC;wBACd,yBAAyB,EAAE,CAAC;oBAC7B,CAAC;oBACD,+GAA+G;oBAC/G,IAAI,CAAC,sBAAsB,GAAG,QAAQ,CAAC;gBACxC,CAAC;aACD,CACD,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5B,EAAE,EAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAG,CAAC;gBACvD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC,CAAC;YACJ,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YACrC,MAAM,MAAM,GAAG,MAAM,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5B,EAAE,EAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAG,CAAC;gBACvD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC,CAAC;YACJ,wEAAwE;YACxE,qDAAqD;YACrD,+DAA+D;YAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAC7E,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;YAClC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAEhD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAE;gBACnD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;YACnC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAEhD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAE;gBACnD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,sDAAsD;YACtD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,mBAAmB,CAC7B,MAAM,CAAC,KAAK,EAAG,CAAC,EAAE,EAClB,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAM,CAAC,IAAI,CAC5C;gBACD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,wEAAwE;YACxE,qDAAqD;YACrD,+DAA+D;YAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAC7E,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAE;gBACnD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5B,EAAE,EAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAG,CAAC;gBACvD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC,CAAC;YAEJ,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,CAAC,CAAC;YAEjF,WAAW,CAAC,MAAM,CAAC,CAAC;YAEpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACpC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAEhD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAE;gBACrE,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YACrC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAEhD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAE;gBACrE,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,sDAAsD;YACtD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,mBAAmB,CAC7B,MAAM,CAAC,KAAK,EAAG,CAAC,EAAE,EAClB,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAM,CAAC,IAAI,CAC5C;gBACD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,wEAAwE;YACxE,qDAAqD;YACrD,+DAA+D;YAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAC7E,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAE;gBACrE,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5B,EAAE,EAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAG,CAAC;gBACvD,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE;aAC9B,CAAC,CAAC,CAAC;YACJ,wEAAwE;YACxE,qDAAqD;YACrD,+DAA+D;YAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,CAAC,CAAC;YACjF,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QACnD,mGAAmG;QACnG,4EAA4E;QAC5E,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE;gBAClE,CAAC,mBAAmB,CAAC,EAAE,IAAI;gBAC3B,KAAK,EAAE,KAAK;aACZ,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAkB,CAAC,CAAC,CAAC;YACpE,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACpD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAEjD,MAAM,WAAW,GAAG,IAAI,UAAU,EAAE,CAAC;YACrC,WAAW,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;YACrD,MAAM,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CACnD,QAAQ,EACR,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAM,CAAC,IAAI,CAC5C,CAAC;YACF,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAExE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,oBAAoB,CAAkB,CAAC,CAAC,CAAC;YACvF,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YAC9D,4GAA4G;YAC5G,uCAAuC;YACvC,MAAM,CAAC,eAAe,CACrB,YAAY,CAAC,UAAU,EACvB,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CACpD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;YAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjB,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAElD,MAAM,WAAW,GAAG,IAAI,UAAU,EAAE,CAAC;YACrC,WAAW,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;YACrD,MAAM,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CACnD,QAAQ,EACR,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAM,CAAC,IAAI,CAC5C,CAAC;YACF,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAExE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,oBAAoB,CAAkB,CAAC,CAAC,CAAC;YACvF,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YACnE,MAAM,CAAC,eAAe,CAAC,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjB,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAElD,MAAM,WAAW,GAAG,IAAI,UAAU,EAAE,CAAC;YACrC,WAAW,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;YACrD,MAAM,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CACnD,QAAQ,EACR,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,KAAM,CAAC,IAAI,CAC5C,CAAC;YACF,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAExE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,oBAAoB,CAAkB,CAAC,CAAC,CAAC;YACvF,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YACnE,MAAM,CAAC,eAAe,CAAC,YAAY,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAChD,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG,2BAA2B,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAEtF,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,GAAG,GAAgD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CACtF,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACT,OAAO,CAAC,CAAC,CAAC,aAAa,CACtB,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EACnE,CAAC,GAAG,CAAC,CACL;YACD,OAAO,CAAC,CAAC,CAAC,wBAAwB,EAAG;SACrC,CACD,CAAC;QAEF,GAAG,CAAC,IAAI,CACP,GAAG,GAAG;aACJ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;aAClC,GAAG,CAA4C,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7D,OAAO,CAAC,CAAC,CAAC,aAAa,CACtB,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,QAAwB,EAAE,EAAE,CAAC,EAC9D,EAAE,CAAC,cAAc,CACjB;YACD,OAAO,CAAC,CAAC,CAAC,wBAAwB,EAAG;SACrC,CAAC,CACH,CAAC;QAEF,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG;YAAE,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG;gBAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,QAAQ,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tMarker,\n\tSegmentGroup,\n\treservedMarkerIdKey,\n\ttype ISegmentPrivate,\n} from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, ReferenceType } from \"../ops.js\";\nimport { clone } from \"../properties.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\ndescribe(\"resetPendingSegmentsToOp\", () => {\n\tlet client: TestClient;\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tclient.startOrUpdateCollaboration(\"local user\");\n\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t});\n\n\tdescribe(\"with a number of nested inserts\", () => {\n\t\tconst insertCount = 5;\n\t\tconst expectedSegmentCount = insertCount * 2 - 1;\n\t\tlet opList: { op: IMergeTreeOp; refSeq: number }[];\n\t\tlet opCount: number = 0;\n\n\t\tfunction applyOpList(cli: TestClient): void {\n\t\t\twhile (opList.length > 0) {\n\t\t\t\tconst op = opList.shift();\n\t\t\t\tif (op) {\n\t\t\t\t\tconst seqOp = cli.makeOpMessage(op.op, ++opCount, op.refSeq);\n\t\t\t\t\tcli.applyMsg(seqOp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbeforeEach(() => {\n\t\t\topList = [];\n\t\t\topCount = 0;\n\n\t\t\tfor (let i = 0; i < insertCount; i++) {\n\t\t\t\tconst op = client.insertTextLocal(i, \"hello\")!;\n\t\t\t\topList.push({ op, refSeq: client.getCurrentSeq() });\n\t\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, i + 1);\n\t\t\t}\n\t\t});\n\n\t\tit(\"acked insertSegment\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"only computes localPartialLengths once\", () => {\n\t\t\t// This test helps verify the asymptotic correctness of rebase.\n\t\t\t// Since local partial length information is reasonably expensive to store and compute compared to how\n\t\t\t// frequently it's used (i.e. only on reconnect), mergeTree has some logic to only do so when requested,\n\t\t\t// and invalidates that info whenever a segment update occurs.\n\t\t\t// This test verifies that local partial length information only gets computed once when regenerating\n\t\t\t// a number of ops for reconnection.\n\t\t\tlet localPartialsComputeCount = 0;\n\t\t\tconst spiedMergeTree = client.mergeTree as unknown as {\n\t\t\t\tlocalPartialsComputed: boolean;\n\t\t\t\t_localPartialsComputed: boolean;\n\t\t\t};\n\t\t\tspiedMergeTree._localPartialsComputed = spiedMergeTree.localPartialsComputed;\n\t\t\tObject.defineProperty(\n\t\t\t\tclient.mergeTree as unknown as { localPartialsComputed: boolean },\n\t\t\t\t\"localPartialsComputed\",\n\t\t\t\t{\n\t\t\t\t\tget() {\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\treturn this._localPartialsComputed as boolean;\n\t\t\t\t\t},\n\t\t\t\t\tset(newValue) {\n\t\t\t\t\t\tif (newValue) {\n\t\t\t\t\t\t\tlocalPartialsComputeCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\tthis._localPartialsComputed = newValue;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\t\t\tapplyOpList(client);\n\t\t\tassert.equal(localPartialsComputeCount, 1);\n\t\t});\n\n\t\tit(\"nacked insertSegment\", async () => {\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"acked removeRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.removeRangeLocal(0, client.getLength())!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked removeRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.removeRangeLocal(0, client.getLength())!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\t// eslint-disable-next-line unicorn/no-array-push-push\n\t\t\topList.push({\n\t\t\t\top: client.regeneratePendingOp(\n\t\t\t\t\topList.shift()!.op,\n\t\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t\t),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked insertSegment and removeRange\", async () => {\n\t\t\topList.push({\n\t\t\t\top: client.removeRangeLocal(0, client.getLength())!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount * 2);\n\n\t\t\tapplyOpList(client);\n\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"acked annotateRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.annotateRangeLocal(0, client.getLength(), { foo: \"bar\" })!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked annotateRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.annotateRangeLocal(0, client.getLength(), { foo: \"bar\" })!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\t// eslint-disable-next-line unicorn/no-array-push-push\n\t\t\topList.push({\n\t\t\t\top: client.regeneratePendingOp(\n\t\t\t\t\topList.shift()!.op,\n\t\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t\t),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked insertSegment and annotateRange\", async () => {\n\t\t\topList.push({\n\t\t\t\top: client.annotateRangeLocal(0, client.getLength(), { foo: \"bar\" })!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount * 2);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\t});\n\n\tdescribe(\"uses original properties on insert\", () => {\n\t\t// Regression tests for an issue where regenerated insert ops would use the properties of a segment\n\t\t// at the time of regeneration rather than its properties at insertion time.\n\t\tit(\"for markers\", () => {\n\t\t\tconst insertOp = client.insertMarkerLocal(0, ReferenceType.Simple, {\n\t\t\t\t[reservedMarkerIdKey]: \"id\",\n\t\t\t\tprop1: \"foo\",\n\t\t\t});\n\t\t\tassert(insertOp);\n\t\t\tconst { segment } = client.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(segment !== undefined && Marker.is(segment));\n\t\t\tclient.annotateMarker(segment, { prop2: \"bar\" });\n\n\t\t\tconst otherClient = new TestClient();\n\t\t\totherClient.startOrUpdateCollaboration(\"other user\");\n\t\t\tconst regeneratedInsert = client.regeneratePendingOp(\n\t\t\t\tinsertOp,\n\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t);\n\t\t\totherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);\n\n\t\t\tconst { segment: otherSegment } = otherClient.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(otherSegment !== undefined && Marker.is(otherSegment));\n\t\t\t// `clone` here is because properties use a Object.create(null); to compare strict equal the prototype chain\n\t\t\t// should therefore not include Object.\n\t\t\tassert.deepStrictEqual(\n\t\t\t\totherSegment.properties,\n\t\t\t\tclone({ [reservedMarkerIdKey]: \"id\", prop1: \"foo\" }),\n\t\t\t);\n\t\t});\n\n\t\tit(\"for text segments\", () => {\n\t\t\tconst insertOp = client.insertTextLocal(0, \"abc\", { prop1: \"foo\" });\n\t\t\tassert(insertOp);\n\t\t\tclient.annotateRangeLocal(0, 3, { prop2: \"bar\" });\n\n\t\t\tconst otherClient = new TestClient();\n\t\t\totherClient.startOrUpdateCollaboration(\"other user\");\n\t\t\tconst regeneratedInsert = client.regeneratePendingOp(\n\t\t\t\tinsertOp,\n\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t);\n\t\t\totherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);\n\n\t\t\tconst { segment: otherSegment } = otherClient.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(otherSegment !== undefined && TextSegment.is(otherSegment));\n\t\t\tassert.deepStrictEqual(otherSegment.properties, clone({ prop1: \"foo\" }));\n\t\t});\n\n\t\tit(\"for text segments with no initial properties\", () => {\n\t\t\tconst insertOp = client.insertTextLocal(0, \"abc\");\n\t\t\tassert(insertOp);\n\t\t\tclient.annotateRangeLocal(0, 3, { prop2: \"bar\" });\n\n\t\t\tconst otherClient = new TestClient();\n\t\t\totherClient.startOrUpdateCollaboration(\"other user\");\n\t\t\tconst regeneratedInsert = client.regeneratePendingOp(\n\t\t\t\tinsertOp,\n\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t);\n\t\t\totherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);\n\n\t\t\tconst { segment: otherSegment } = otherClient.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(otherSegment !== undefined && TextSegment.is(otherSegment));\n\t\t\tassert.deepStrictEqual(otherSegment.properties, undefined);\n\t\t});\n\t});\n});\n\ndescribe(\"resetPendingSegmentsToOp.rebase\", () => {\n\tit(\"rebase with oustanding ops\", () => {\n\t\tconst clients = createClientsAtInitialState({ initialState: \"0123456789\" }, \"A\", \"B\");\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tconst ops: [ISequencedDocumentMessage, SegmentGroup][] = Array.from({ length: 10 }).map(\n\t\t\t(_, i) => [\n\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\tclients.A.annotateRangeLocal(0, clients.A.getLength(), { prop: i }),\n\t\t\t\t\ti + 1,\n\t\t\t\t),\n\t\t\t\tclients.A.peekPendingSegmentGroups()!,\n\t\t\t],\n\t\t);\n\n\t\tops.push(\n\t\t\t...ops\n\t\t\t\t.splice(Math.floor(ops.length / 2))\n\t\t\t\t.map<[ISequencedDocumentMessage, SegmentGroup]>(([op, sg]) => [\n\t\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\t\tclients.A.regeneratePendingOp(op.contents as IMergeTreeOp, sg),\n\t\t\t\t\t\top.sequenceNumber,\n\t\t\t\t\t),\n\t\t\t\t\tclients.A.peekPendingSegmentGroups()!,\n\t\t\t\t]),\n\t\t);\n\n\t\tfor (const [op] of ops) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate();\n\t});\n});\n"]}
1
+ {"version":3,"file":"resetPendingSegmentsToOp.spec.js","sourceRoot":"","sources":["../../src/test/resetPendingSegmentsToOp.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tMarker,\n\tSegmentGroup,\n\treservedMarkerIdKey,\n\ttype ISegmentPrivate,\n} from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, ReferenceType } from \"../ops.js\";\nimport { clone } from \"../properties.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\ndescribe(\"resetPendingSegmentsToOp\", () => {\n\tlet client: TestClient;\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tclient.startOrUpdateCollaboration(\"local user\");\n\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t});\n\n\tdescribe(\"with a number of nested inserts\", () => {\n\t\tconst insertCount = 5;\n\t\tconst expectedSegmentCount = insertCount * 2 - 1;\n\t\tlet opList: { op: IMergeTreeOp; refSeq: number }[];\n\t\tlet opCount: number = 0;\n\n\t\tfunction applyOpList(cli: TestClient): void {\n\t\t\twhile (opList.length > 0) {\n\t\t\t\tconst op = opList.shift();\n\t\t\t\tif (op) {\n\t\t\t\t\tconst seqOp = cli.makeOpMessage(op.op, ++opCount, op.refSeq);\n\t\t\t\t\tcli.applyMsg(seqOp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbeforeEach(() => {\n\t\t\topList = [];\n\t\t\topCount = 0;\n\n\t\t\tfor (let i = 0; i < insertCount; i++) {\n\t\t\t\tconst op = client.insertTextLocal(i, \"hello\")!;\n\t\t\t\topList.push({ op, refSeq: client.getCurrentSeq() });\n\t\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, i + 1);\n\t\t\t}\n\t\t});\n\n\t\tit(\"acked insertSegment\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"only computes localPartialLengths once\", () => {\n\t\t\t// This test helps verify the asymptotic correctness of rebase.\n\t\t\t// Since local partial length information is reasonably expensive to store and compute compared to how\n\t\t\t// frequently it's used (i.e. only on reconnect), mergeTree has some logic to only do so when requested,\n\t\t\t// and invalidates that info whenever a segment update occurs.\n\t\t\t// This test verifies that local partial length information only gets computed once when regenerating\n\t\t\t// a number of ops for reconnection.\n\t\t\tlet localPartialsComputeCount = 0;\n\t\t\tconst spiedMergeTree = client.mergeTree as unknown as {\n\t\t\t\tlocalPartialsComputed: boolean;\n\t\t\t\t_localPartialsComputed: boolean;\n\t\t\t};\n\t\t\tspiedMergeTree._localPartialsComputed = spiedMergeTree.localPartialsComputed;\n\t\t\tObject.defineProperty(\n\t\t\t\tclient.mergeTree as unknown as { localPartialsComputed: boolean },\n\t\t\t\t\"localPartialsComputed\",\n\t\t\t\t{\n\t\t\t\t\tget() {\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\treturn this._localPartialsComputed as boolean;\n\t\t\t\t\t},\n\t\t\t\t\tset(newValue) {\n\t\t\t\t\t\tif (newValue) {\n\t\t\t\t\t\t\tlocalPartialsComputeCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\tthis._localPartialsComputed = newValue;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\t\t\tapplyOpList(client);\n\t\t\tassert.equal(localPartialsComputeCount, 1);\n\t\t});\n\n\t\tit(\"nacked insertSegment\", async () => {\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"acked removeRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.removeRangeLocal(0, client.getLength())!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked removeRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.removeRangeLocal(0, client.getLength())!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\n\t\t\topList.push({\n\t\t\t\top: client.regeneratePendingOp(\n\t\t\t\t\topList.shift()!.op,\n\t\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t\t),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked insertSegment and removeRange\", async () => {\n\t\t\topList.push({\n\t\t\t\top: client.removeRangeLocal(0, client.getLength())!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount * 2);\n\n\t\t\tapplyOpList(client);\n\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"acked annotateRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.annotateRangeLocal(0, client.getLength(), { foo: \"bar\" })!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked annotateRange\", async () => {\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\n\t\t\topList.push({\n\t\t\t\top: client.annotateRangeLocal(0, client.getLength(), { foo: \"bar\" })!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\n\t\t\topList.push({\n\t\t\t\top: client.regeneratePendingOp(\n\t\t\t\t\topList.shift()!.op,\n\t\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t\t),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\n\t\tit(\"nacked insertSegment and annotateRange\", async () => {\n\t\t\topList.push({\n\t\t\t\top: client.annotateRangeLocal(0, client.getLength(), { foo: \"bar\" })!,\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t});\n\t\t\tconst oldops = opList;\n\t\t\tconst pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];\n\t\t\topList = oldops.map((op) => ({\n\t\t\t\top: client.regeneratePendingOp(op.op, pending.shift()!),\n\t\t\t\trefSeq: client.getCurrentSeq(),\n\t\t\t}));\n\t\t\t// we expect a nack op per segment since our original ops split segments\n\t\t\t// we should expect mores nack ops then original ops.\n\t\t\t// only the first op didn't split a segment, all the others did\n\t\t\tassert.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount * 2);\n\t\t\tapplyOpList(client);\n\t\t\tassert(client.mergeTree.pendingSegments?.empty);\n\t\t});\n\t});\n\n\tdescribe(\"uses original properties on insert\", () => {\n\t\t// Regression tests for an issue where regenerated insert ops would use the properties of a segment\n\t\t// at the time of regeneration rather than its properties at insertion time.\n\t\tit(\"for markers\", () => {\n\t\t\tconst insertOp = client.insertMarkerLocal(0, ReferenceType.Simple, {\n\t\t\t\t[reservedMarkerIdKey]: \"id\",\n\t\t\t\tprop1: \"foo\",\n\t\t\t});\n\t\t\tassert(insertOp);\n\t\t\tconst { segment } = client.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(segment !== undefined && Marker.is(segment));\n\t\t\tclient.annotateMarker(segment, { prop2: \"bar\" });\n\n\t\t\tconst otherClient = new TestClient();\n\t\t\totherClient.startOrUpdateCollaboration(\"other user\");\n\t\t\tconst regeneratedInsert = client.regeneratePendingOp(\n\t\t\t\tinsertOp,\n\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t);\n\t\t\totherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);\n\n\t\t\tconst { segment: otherSegment } = otherClient.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(otherSegment !== undefined && Marker.is(otherSegment));\n\t\t\t// `clone` here is because properties use a Object.create(null); to compare strict equal the prototype chain\n\t\t\t// should therefore not include Object.\n\t\t\tassert.deepStrictEqual(\n\t\t\t\totherSegment.properties,\n\t\t\t\tclone({ [reservedMarkerIdKey]: \"id\", prop1: \"foo\" }),\n\t\t\t);\n\t\t});\n\n\t\tit(\"for text segments\", () => {\n\t\t\tconst insertOp = client.insertTextLocal(0, \"abc\", { prop1: \"foo\" });\n\t\t\tassert(insertOp);\n\t\t\tclient.annotateRangeLocal(0, 3, { prop2: \"bar\" });\n\n\t\t\tconst otherClient = new TestClient();\n\t\t\totherClient.startOrUpdateCollaboration(\"other user\");\n\t\t\tconst regeneratedInsert = client.regeneratePendingOp(\n\t\t\t\tinsertOp,\n\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t);\n\t\t\totherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);\n\n\t\t\tconst { segment: otherSegment } = otherClient.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(otherSegment !== undefined && TextSegment.is(otherSegment));\n\t\t\tassert.deepStrictEqual(otherSegment.properties, clone({ prop1: \"foo\" }));\n\t\t});\n\n\t\tit(\"for text segments with no initial properties\", () => {\n\t\t\tconst insertOp = client.insertTextLocal(0, \"abc\");\n\t\t\tassert(insertOp);\n\t\t\tclient.annotateRangeLocal(0, 3, { prop2: \"bar\" });\n\n\t\t\tconst otherClient = new TestClient();\n\t\t\totherClient.startOrUpdateCollaboration(\"other user\");\n\t\t\tconst regeneratedInsert = client.regeneratePendingOp(\n\t\t\t\tinsertOp,\n\t\t\t\tclient.mergeTree.pendingSegments.first!.data,\n\t\t\t);\n\t\t\totherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);\n\n\t\t\tconst { segment: otherSegment } = otherClient.getContainingSegment<ISegmentPrivate>(0);\n\t\t\tassert(otherSegment !== undefined && TextSegment.is(otherSegment));\n\t\t\tassert.deepStrictEqual(otherSegment.properties, undefined);\n\t\t});\n\t});\n});\n\ndescribe(\"resetPendingSegmentsToOp.rebase\", () => {\n\tit(\"rebase with oustanding ops\", () => {\n\t\tconst clients = createClientsAtInitialState({ initialState: \"0123456789\" }, \"A\", \"B\");\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tconst ops: [ISequencedDocumentMessage, SegmentGroup][] = Array.from({ length: 10 }).map(\n\t\t\t(_, i) => [\n\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\tclients.A.annotateRangeLocal(0, clients.A.getLength(), { prop: i }),\n\t\t\t\t\ti + 1,\n\t\t\t\t),\n\t\t\t\tclients.A.peekPendingSegmentGroups()!,\n\t\t\t],\n\t\t);\n\n\t\tops.push(\n\t\t\t...ops\n\t\t\t\t.splice(Math.floor(ops.length / 2))\n\t\t\t\t.map<[ISequencedDocumentMessage, SegmentGroup]>(([op, sg]) => [\n\t\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\t\tclients.A.regeneratePendingOp(op.contents as IMergeTreeOp, sg),\n\t\t\t\t\t\top.sequenceNumber,\n\t\t\t\t\t),\n\t\t\t\t\tclients.A.peekPendingSegmentGroups()!,\n\t\t\t\t]),\n\t\t);\n\n\t\tfor (const [op] of ops) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate();\n\t});\n});\n"]}
@@ -14,8 +14,11 @@ describe("segmentGroupCollection", () => {
14
14
  beforeEach(() => {
15
15
  parent = new MergeBlock(1);
16
16
  const newSeg = (segment = overwriteInfo(TextSegment.make("abc"), {
17
- clientId: 0,
18
- seq: 1,
17
+ insert: {
18
+ type: "insert",
19
+ clientId: 0,
20
+ seq: 1,
21
+ },
19
22
  }));
20
23
  assignChild(parent, newSeg, 0);
21
24
  segmentGroups = segment.segmentGroups = new SegmentGroupCollection(newSeg);
@@ -53,8 +56,11 @@ describe("segmentGroupCollection", () => {
53
56
  segmentGroups.enqueue({ segments: [], localSeq: 1, refSeq: 0 });
54
57
  }
55
58
  const segmentCopy = overwriteInfo(TextSegment.make(""), {
56
- clientId: 0,
57
- seq: 1,
59
+ insert: {
60
+ type: "insert",
61
+ clientId: 0,
62
+ seq: 1,
63
+ },
58
64
  });
59
65
  assignChild(parent, segmentCopy, parent.childCount++);
60
66
  const segmentGroupCopy = new SegmentGroupCollection(segmentCopy);
@@ -1 +1 @@
1
- {"version":3,"file":"segmentGroupCollection.spec.js","sourceRoot":"","sources":["../../src/test/segmentGroupCollection.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { assignChild, MergeBlock, type ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { SegmentGroupCollection } from \"../segmentGroupCollection.js\";\nimport { IInsertionInfo, overwriteInfo } from \"../segmentInfos.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\ndescribe(\"segmentGroupCollection\", () => {\n\tlet parent: MergeBlock;\n\tlet segment: ISegmentPrivate;\n\tlet segmentGroups: SegmentGroupCollection;\n\tbeforeEach(() => {\n\t\tparent = new MergeBlock(1);\n\t\tconst newSeg = (segment = overwriteInfo<IInsertionInfo>(TextSegment.make(\"abc\"), {\n\t\t\tclientId: 0,\n\t\t\tseq: 1,\n\t\t}));\n\t\tassignChild(parent, newSeg, 0);\n\n\t\tsegmentGroups = segment.segmentGroups = new SegmentGroupCollection(newSeg);\n\t});\n\tit(\".empty\", () => {\n\t\tassert(segmentGroups.empty);\n\t});\n\n\tit(\".size\", () => {\n\t\tassert.equal(segmentGroups.size, 0);\n\t});\n\n\tit(\".enqueue\", () => {\n\t\tconst segmentGroup = { segments: [], localSeq: 1, refSeq: 0 };\n\t\tsegmentGroups.enqueue(segmentGroup);\n\n\t\tassert(!segmentGroups.empty);\n\t\tassert.equal(segmentGroups.size, 1);\n\t\tassert.equal(segmentGroup.segments.length, 1);\n\t\tassert.equal(segmentGroup.segments[0], segment);\n\t});\n\n\tit(\".dequeue\", () => {\n\t\tconst segmentGroup = { segments: [], localSeq: 1, refSeq: 0 };\n\t\tsegmentGroups.enqueue(segmentGroup);\n\t\tconst segmentGroupCount = 6;\n\t\twhile (segmentGroups.size < segmentGroupCount) {\n\t\t\tsegmentGroups.enqueue({ segments: [], localSeq: 1, refSeq: 0 });\n\t\t}\n\n\t\tconst dequeuedSegmentGroup = segmentGroups.dequeue();\n\n\t\tassert.equal(segmentGroups.size, segmentGroupCount - 1);\n\t\tassert.equal(dequeuedSegmentGroup?.segments.length, 1);\n\t\tassert.equal(dequeuedSegmentGroup.segments[0], segment);\n\t\tassert.equal(dequeuedSegmentGroup, segmentGroup);\n\t});\n\n\tit(\".copyTo\", () => {\n\t\tconst segmentGroupCount = 6;\n\t\twhile (segmentGroups.size < segmentGroupCount) {\n\t\t\tsegmentGroups.enqueue({ segments: [], localSeq: 1, refSeq: 0 });\n\t\t}\n\n\t\tconst segmentCopy = overwriteInfo<IInsertionInfo>(TextSegment.make(\"\"), {\n\t\t\tclientId: 0,\n\t\t\tseq: 1,\n\t\t});\n\t\tassignChild(parent, segmentCopy, parent.childCount++);\n\n\t\tconst segmentGroupCopy = new SegmentGroupCollection(segmentCopy);\n\t\tsegmentGroups.copyTo(segmentGroupCopy);\n\n\t\tassert.equal(segmentGroups.size, segmentGroupCount);\n\t\tassert.equal(segmentGroupCopy.size, segmentGroupCount);\n\n\t\twhile (!segmentGroups.empty || !segmentGroupCopy.empty) {\n\t\t\tconst segmentGroup = segmentGroups.dequeue();\n\t\t\tconst copySegmentGroup = segmentGroupCopy.dequeue();\n\n\t\t\tassert.equal(segmentGroup, copySegmentGroup);\n\t\t\tassert.equal(segmentGroup?.segments.length, 2);\n\t\t\tassert.equal(segmentGroup.segments[0], segment);\n\t\t\tassert.equal(segmentGroup.segments[1], segmentCopy);\n\t\t}\n\t});\n});\n"]}
1
+ {"version":3,"file":"segmentGroupCollection.spec.js","sourceRoot":"","sources":["../../src/test/segmentGroupCollection.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { assignChild, MergeBlock, type ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { SegmentGroupCollection } from \"../segmentGroupCollection.js\";\nimport { IHasInsertionInfo, overwriteInfo } from \"../segmentInfos.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\ndescribe(\"segmentGroupCollection\", () => {\n\tlet parent: MergeBlock;\n\tlet segment: ISegmentPrivate;\n\tlet segmentGroups: SegmentGroupCollection;\n\tbeforeEach(() => {\n\t\tparent = new MergeBlock(1);\n\t\tconst newSeg = (segment = overwriteInfo<IHasInsertionInfo>(TextSegment.make(\"abc\"), {\n\t\t\tinsert: {\n\t\t\t\ttype: \"insert\",\n\t\t\t\tclientId: 0,\n\t\t\t\tseq: 1,\n\t\t\t},\n\t\t}));\n\t\tassignChild(parent, newSeg, 0);\n\n\t\tsegmentGroups = segment.segmentGroups = new SegmentGroupCollection(newSeg);\n\t});\n\tit(\".empty\", () => {\n\t\tassert(segmentGroups.empty);\n\t});\n\n\tit(\".size\", () => {\n\t\tassert.equal(segmentGroups.size, 0);\n\t});\n\n\tit(\".enqueue\", () => {\n\t\tconst segmentGroup = { segments: [], localSeq: 1, refSeq: 0 };\n\t\tsegmentGroups.enqueue(segmentGroup);\n\n\t\tassert(!segmentGroups.empty);\n\t\tassert.equal(segmentGroups.size, 1);\n\t\tassert.equal(segmentGroup.segments.length, 1);\n\t\tassert.equal(segmentGroup.segments[0], segment);\n\t});\n\n\tit(\".dequeue\", () => {\n\t\tconst segmentGroup = { segments: [], localSeq: 1, refSeq: 0 };\n\t\tsegmentGroups.enqueue(segmentGroup);\n\t\tconst segmentGroupCount = 6;\n\t\twhile (segmentGroups.size < segmentGroupCount) {\n\t\t\tsegmentGroups.enqueue({ segments: [], localSeq: 1, refSeq: 0 });\n\t\t}\n\n\t\tconst dequeuedSegmentGroup = segmentGroups.dequeue();\n\n\t\tassert.equal(segmentGroups.size, segmentGroupCount - 1);\n\t\tassert.equal(dequeuedSegmentGroup?.segments.length, 1);\n\t\tassert.equal(dequeuedSegmentGroup.segments[0], segment);\n\t\tassert.equal(dequeuedSegmentGroup, segmentGroup);\n\t});\n\n\tit(\".copyTo\", () => {\n\t\tconst segmentGroupCount = 6;\n\t\twhile (segmentGroups.size < segmentGroupCount) {\n\t\t\tsegmentGroups.enqueue({ segments: [], localSeq: 1, refSeq: 0 });\n\t\t}\n\n\t\tconst segmentCopy = overwriteInfo<IHasInsertionInfo>(TextSegment.make(\"\"), {\n\t\t\tinsert: {\n\t\t\t\ttype: \"insert\",\n\t\t\t\tclientId: 0,\n\t\t\t\tseq: 1,\n\t\t\t},\n\t\t});\n\t\tassignChild(parent, segmentCopy, parent.childCount++);\n\n\t\tconst segmentGroupCopy = new SegmentGroupCollection(segmentCopy);\n\t\tsegmentGroups.copyTo(segmentGroupCopy);\n\n\t\tassert.equal(segmentGroups.size, segmentGroupCount);\n\t\tassert.equal(segmentGroupCopy.size, segmentGroupCount);\n\n\t\twhile (!segmentGroups.empty || !segmentGroupCopy.empty) {\n\t\t\tconst segmentGroup = segmentGroups.dequeue();\n\t\t\tconst copySegmentGroup = segmentGroupCopy.dequeue();\n\n\t\t\tassert.equal(segmentGroup, copySegmentGroup);\n\t\t\tassert.equal(segmentGroup?.segments.length, 2);\n\t\t\tassert.equal(segmentGroup.segments[0], segment);\n\t\t\tassert.equal(segmentGroup.segments[1], segmentCopy);\n\t\t}\n\t});\n});\n"]}
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=stamps.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stamps.spec.d.ts","sourceRoot":"","sources":["../../src/test/stamps.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,105 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { strict as assert } from "node:assert";
6
+ import { UnassignedSequenceNumber } from "../constants.js";
7
+ import * as opstampUtils from "../stamps.js";
8
+ function lessThan(a, b) {
9
+ const result = opstampUtils.lessThan(a, b);
10
+ // Validate that this gives a consistent result with some other ways to compute the same thing
11
+ const fromComparison = opstampUtils.compare(a, b) === -1;
12
+ const fromGte = !opstampUtils.gte(a, b);
13
+ assert.strictEqual(result, fromComparison);
14
+ assert.strictEqual(result, fromGte);
15
+ return result;
16
+ }
17
+ function greaterThan(a, b) {
18
+ const result = opstampUtils.greaterThan(a, b);
19
+ // Validate that this gives a consistent result with some other ways to compute the same thing
20
+ const fromComparison = opstampUtils.compare(a, b) === 1;
21
+ const fromLte = !opstampUtils.lte(a, b);
22
+ assert.strictEqual(result, fromComparison);
23
+ assert.strictEqual(result, fromLte);
24
+ return result;
25
+ }
26
+ /**
27
+ * Validate that a list of operation stamps is in strictly increasing order in several different ways using the comparison
28
+ * operation stamp utility methods.
29
+ */
30
+ function expectStrictlyIncreasing(list) {
31
+ for (let i = 0; i < list.length - 1; i++) {
32
+ assert.ok(lessThan(list[i], list[i + 1]), `List not strictly increasing by lessThan: ${JSON.stringify(list[i])} >= ${JSON.stringify(list[i + 1])}`);
33
+ assert.ok(greaterThan(list[i + 1], list[i]), `List not strictly increasing by greaterThan: ${JSON.stringify(list[i + 1])} <= ${JSON.stringify(list[i])}`);
34
+ }
35
+ }
36
+ describe("opstampUtils", () => {
37
+ const acked1 = { clientId: 1, seq: 1 };
38
+ const acked2 = { clientId: 2, seq: 2 };
39
+ const acked3 = { clientId: 1, seq: 3 };
40
+ const local1 = { clientId: 1, seq: UnassignedSequenceNumber, localSeq: 1 };
41
+ const local2 = { clientId: 1, seq: UnassignedSequenceNumber, localSeq: 2 };
42
+ describe("equality", () => {
43
+ it("returns true for reference equal stamps", () => {
44
+ for (const stamp of [acked1, acked2, acked3, local1, local2]) {
45
+ assert.ok(opstampUtils.equal(stamp, stamp));
46
+ }
47
+ });
48
+ it("returns true for equal stamps", () => {
49
+ for (const stamp of [acked1, acked2, acked3, local1, local2]) {
50
+ assert.ok(opstampUtils.equal(stamp, { ...stamp }));
51
+ }
52
+ });
53
+ it("returns false for different stamps", () => {
54
+ assert.ok(!opstampUtils.equal(acked1, acked2));
55
+ assert.ok(!opstampUtils.equal(acked1, acked3));
56
+ assert.ok(!opstampUtils.equal(acked1, local1));
57
+ assert.ok(!opstampUtils.equal(acked1, local2));
58
+ assert.ok(!opstampUtils.equal(local1, local2));
59
+ });
60
+ });
61
+ describe("comparison", () => {
62
+ it("orders stamps correctly", () => {
63
+ expectStrictlyIncreasing([acked1, acked2, acked3, local1, local2]);
64
+ });
65
+ it("compare can sort lists", () => {
66
+ const list = [acked3, local1, acked1, local2, acked2];
67
+ list.sort(opstampUtils.compare);
68
+ assert.deepEqual(list, [acked1, acked2, acked3, local1, local2]);
69
+ });
70
+ });
71
+ describe("spliceIntoList", () => {
72
+ it("inserts unacked into empty list", () => {
73
+ const list = [];
74
+ opstampUtils.spliceIntoList(list, local1);
75
+ assert.deepStrictEqual(list, [local1]);
76
+ });
77
+ it("inserts acked into empty list", () => {
78
+ const list = [];
79
+ opstampUtils.spliceIntoList(list, acked1);
80
+ assert.deepStrictEqual(list, [acked1]);
81
+ });
82
+ it("inserts unacked after acked", () => {
83
+ const list = [acked1];
84
+ opstampUtils.spliceIntoList(list, local1);
85
+ assert.deepStrictEqual(list, [acked1, local1]);
86
+ });
87
+ it("inserts acked before unacked", () => {
88
+ const list = [acked1, acked2, local1];
89
+ opstampUtils.spliceIntoList(list, acked3);
90
+ assert.deepStrictEqual(list, [acked1, acked2, acked3, local1]);
91
+ });
92
+ it("inserts acked before single unacked", () => {
93
+ const list = [local1];
94
+ opstampUtils.spliceIntoList(list, acked2);
95
+ assert.deepStrictEqual(list, [acked2, local1]);
96
+ });
97
+ it("inserts local seqs at end", () => {
98
+ const list = [acked1, acked2];
99
+ opstampUtils.spliceIntoList(list, local1);
100
+ opstampUtils.spliceIntoList(list, local2);
101
+ assert.deepStrictEqual(list, [acked1, acked2, local1, local2]);
102
+ });
103
+ });
104
+ });
105
+ //# sourceMappingURL=stamps.spec.js.map