@fluidframework/merge-tree 2.0.0-internal.8.0.0 → 2.0.0-rc.1.0.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 (481) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +0 -6
  3. package/api-extractor-esm.json +17 -0
  4. package/api-extractor-lint.json +1 -10
  5. package/api-extractor.json +0 -4
  6. package/api-report/merge-tree.api.md +4 -9
  7. package/dist/client.d.ts +0 -7
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +0 -7
  10. package/dist/client.js.map +1 -1
  11. package/dist/merge-tree-alpha.d.ts +27 -12
  12. package/dist/merge-tree-beta.d.ts +0 -16
  13. package/dist/merge-tree-public.d.ts +0 -16
  14. package/dist/merge-tree-untrimmed.d.ts +5 -29
  15. package/dist/mergeTree.d.ts +0 -17
  16. package/dist/mergeTree.d.ts.map +1 -1
  17. package/dist/mergeTree.js +0 -130
  18. package/dist/mergeTree.js.map +1 -1
  19. package/dist/ops.d.ts +1 -1
  20. package/dist/ops.js +1 -1
  21. package/dist/ops.js.map +1 -1
  22. package/dist/revertibles.d.ts +4 -4
  23. package/dist/revertibles.js +3 -3
  24. package/dist/revertibles.js.map +1 -1
  25. package/dist/test/Insertion.perf.spec.d.ts +6 -0
  26. package/dist/test/Insertion.perf.spec.d.ts.map +1 -0
  27. package/dist/test/Insertion.perf.spec.js +113 -0
  28. package/dist/test/Insertion.perf.spec.js.map +1 -0
  29. package/dist/test/PartialLengths.perf.spec.d.ts +6 -0
  30. package/dist/test/PartialLengths.perf.spec.d.ts.map +1 -0
  31. package/dist/test/PartialLengths.perf.spec.js +67 -0
  32. package/dist/test/PartialLengths.perf.spec.js.map +1 -0
  33. package/dist/test/Removal.perf.spec.d.ts +6 -0
  34. package/dist/test/Removal.perf.spec.d.ts.map +1 -0
  35. package/dist/test/Removal.perf.spec.js +166 -0
  36. package/dist/test/Removal.perf.spec.js.map +1 -0
  37. package/dist/test/Snapshot.perf.spec.d.ts +6 -0
  38. package/dist/test/Snapshot.perf.spec.d.ts.map +1 -0
  39. package/dist/test/Snapshot.perf.spec.js +33 -0
  40. package/dist/test/Snapshot.perf.spec.js.map +1 -0
  41. package/dist/test/attributionCollection.perf.spec.d.ts +6 -0
  42. package/dist/test/attributionCollection.perf.spec.d.ts.map +1 -0
  43. package/dist/test/attributionCollection.perf.spec.js +231 -0
  44. package/dist/test/attributionCollection.perf.spec.js.map +1 -0
  45. package/dist/test/attributionCollection.spec.d.ts +6 -0
  46. package/dist/test/attributionCollection.spec.d.ts.map +1 -0
  47. package/dist/test/attributionCollection.spec.js +486 -0
  48. package/dist/test/attributionCollection.spec.js.map +1 -0
  49. package/dist/test/attributionPolicy.spec.d.ts +6 -0
  50. package/dist/test/attributionPolicy.spec.d.ts.map +1 -0
  51. package/dist/test/attributionPolicy.spec.js +189 -0
  52. package/dist/test/attributionPolicy.spec.js.map +1 -0
  53. package/dist/test/beastTest.d.ts +54 -0
  54. package/dist/test/beastTest.d.ts.map +1 -0
  55. package/dist/test/beastTest.js +1333 -0
  56. package/dist/test/beastTest.js.map +1 -0
  57. package/dist/test/client.annotateMarker.spec.d.ts +6 -0
  58. package/dist/test/client.annotateMarker.spec.d.ts.map +1 -0
  59. package/dist/test/client.annotateMarker.spec.js +45 -0
  60. package/dist/test/client.annotateMarker.spec.js.map +1 -0
  61. package/dist/test/client.apis.d.ts +7 -0
  62. package/dist/test/client.apis.d.ts.map +1 -0
  63. package/dist/test/client.apis.js +72 -0
  64. package/dist/test/client.apis.js.map +1 -0
  65. package/dist/test/client.applyMsg.spec.d.ts +6 -0
  66. package/dist/test/client.applyMsg.spec.d.ts.map +1 -0
  67. package/dist/test/client.applyMsg.spec.js +500 -0
  68. package/dist/test/client.applyMsg.spec.js.map +1 -0
  69. package/dist/test/client.applyStashedOpFarm.spec.d.ts +12 -0
  70. package/dist/test/client.applyStashedOpFarm.spec.d.ts.map +1 -0
  71. package/dist/test/client.applyStashedOpFarm.spec.js +144 -0
  72. package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -0
  73. package/dist/test/client.attributionFarm.spec.d.ts +7 -0
  74. package/dist/test/client.attributionFarm.spec.d.ts.map +1 -0
  75. package/dist/test/client.attributionFarm.spec.js +96 -0
  76. package/dist/test/client.attributionFarm.spec.js.map +1 -0
  77. package/dist/test/client.conflictFarm.spec.d.ts +15 -0
  78. package/dist/test/client.conflictFarm.spec.d.ts.map +1 -0
  79. package/dist/test/client.conflictFarm.spec.js +88 -0
  80. package/dist/test/client.conflictFarm.spec.js.map +1 -0
  81. package/dist/test/client.getPosition.spec.d.ts +6 -0
  82. package/dist/test/client.getPosition.spec.d.ts.map +1 -0
  83. package/dist/test/client.getPosition.spec.js +54 -0
  84. package/dist/test/client.getPosition.spec.js.map +1 -0
  85. package/dist/test/client.localReference.spec.d.ts +6 -0
  86. package/dist/test/client.localReference.spec.d.ts.map +1 -0
  87. package/dist/test/client.localReference.spec.js +439 -0
  88. package/dist/test/client.localReference.spec.js.map +1 -0
  89. package/dist/test/client.localReferenceFarm.spec.d.ts +6 -0
  90. package/dist/test/client.localReferenceFarm.spec.d.ts.map +1 -0
  91. package/dist/test/client.localReferenceFarm.spec.js +88 -0
  92. package/dist/test/client.localReferenceFarm.spec.js.map +1 -0
  93. package/dist/test/client.rebasePosition.spec.d.ts +6 -0
  94. package/dist/test/client.rebasePosition.spec.d.ts.map +1 -0
  95. package/dist/test/client.rebasePosition.spec.js +102 -0
  96. package/dist/test/client.rebasePosition.spec.js.map +1 -0
  97. package/dist/test/client.reconnectFarm.spec.d.ts +12 -0
  98. package/dist/test/client.reconnectFarm.spec.d.ts.map +1 -0
  99. package/dist/test/client.reconnectFarm.spec.js +91 -0
  100. package/dist/test/client.reconnectFarm.spec.js.map +1 -0
  101. package/dist/test/client.replay.spec.d.ts +6 -0
  102. package/dist/test/client.replay.spec.d.ts.map +1 -0
  103. package/dist/test/client.replay.spec.js +85 -0
  104. package/dist/test/client.replay.spec.js.map +1 -0
  105. package/dist/test/client.rollback.spec.d.ts +6 -0
  106. package/dist/test/client.rollback.spec.d.ts.map +1 -0
  107. package/dist/test/client.rollback.spec.js +453 -0
  108. package/dist/test/client.rollback.spec.js.map +1 -0
  109. package/dist/test/client.rollbackFarm.spec.d.ts +6 -0
  110. package/dist/test/client.rollbackFarm.spec.d.ts.map +1 -0
  111. package/dist/test/client.rollbackFarm.spec.js +48 -0
  112. package/dist/test/client.rollbackFarm.spec.js.map +1 -0
  113. package/dist/test/client.searchForMarker.spec.d.ts +6 -0
  114. package/dist/test/client.searchForMarker.spec.d.ts.map +1 -0
  115. package/dist/test/client.searchForMarker.spec.js +446 -0
  116. package/dist/test/client.searchForMarker.spec.js.map +1 -0
  117. package/dist/test/client.walkSegments.spec.d.ts +6 -0
  118. package/dist/test/client.walkSegments.spec.d.ts.map +1 -0
  119. package/dist/test/client.walkSegments.spec.js +54 -0
  120. package/dist/test/client.walkSegments.spec.js.map +1 -0
  121. package/dist/test/collections.list.spec.d.ts +6 -0
  122. package/dist/test/collections.list.spec.d.ts.map +1 -0
  123. package/dist/test/collections.list.spec.js +84 -0
  124. package/dist/test/collections.list.spec.js.map +1 -0
  125. package/dist/test/createInsertOnlyAttributionPolicy.spec.d.ts +6 -0
  126. package/dist/test/createInsertOnlyAttributionPolicy.spec.d.ts.map +1 -0
  127. package/dist/test/createInsertOnlyAttributionPolicy.spec.js +35 -0
  128. package/dist/test/createInsertOnlyAttributionPolicy.spec.js.map +1 -0
  129. package/dist/test/index.d.ts +13 -0
  130. package/dist/test/index.d.ts.map +1 -0
  131. package/dist/test/index.js +88 -0
  132. package/dist/test/index.js.map +1 -0
  133. package/dist/test/mergeTree.annotate.deltaCallback.spec.d.ts +6 -0
  134. package/dist/test/mergeTree.annotate.deltaCallback.spec.d.ts.map +1 -0
  135. package/dist/test/mergeTree.annotate.deltaCallback.spec.js +142 -0
  136. package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -0
  137. package/dist/test/mergeTree.annotate.spec.d.ts +6 -0
  138. package/dist/test/mergeTree.annotate.spec.d.ts.map +1 -0
  139. package/dist/test/mergeTree.annotate.spec.js +448 -0
  140. package/dist/test/mergeTree.annotate.spec.js.map +1 -0
  141. package/dist/test/mergeTree.insert.deltaCallback.spec.d.ts +6 -0
  142. package/dist/test/mergeTree.insert.deltaCallback.spec.d.ts.map +1 -0
  143. package/dist/test/mergeTree.insert.deltaCallback.spec.js +126 -0
  144. package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -0
  145. package/dist/test/mergeTree.insertingWalk.spec.d.ts +6 -0
  146. package/dist/test/mergeTree.insertingWalk.spec.d.ts.map +1 -0
  147. package/dist/test/mergeTree.insertingWalk.spec.js +279 -0
  148. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -0
  149. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.d.ts +6 -0
  150. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.d.ts.map +1 -0
  151. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +178 -0
  152. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -0
  153. package/dist/test/mergeTree.markRangeRemoved.spec.d.ts +6 -0
  154. package/dist/test/mergeTree.markRangeRemoved.spec.d.ts.map +1 -0
  155. package/dist/test/mergeTree.markRangeRemoved.spec.js +130 -0
  156. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -0
  157. package/dist/test/mergeTree.walk.spec.d.ts +6 -0
  158. package/dist/test/mergeTree.walk.spec.d.ts.map +1 -0
  159. package/dist/test/mergeTree.walk.spec.js +63 -0
  160. package/dist/test/mergeTree.walk.spec.js.map +1 -0
  161. package/dist/test/mergeTree.zamboni.spec.d.ts +6 -0
  162. package/dist/test/mergeTree.zamboni.spec.d.ts.map +1 -0
  163. package/dist/test/mergeTree.zamboni.spec.js +52 -0
  164. package/dist/test/mergeTree.zamboni.spec.js.map +1 -0
  165. package/dist/test/mergeTreeOperationRunner.d.ts +63 -0
  166. package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -0
  167. package/dist/test/mergeTreeOperationRunner.js +245 -0
  168. package/dist/test/mergeTreeOperationRunner.js.map +1 -0
  169. package/dist/test/mergeTreeOperationRunner.spec.d.ts +6 -0
  170. package/dist/test/mergeTreeOperationRunner.spec.d.ts.map +1 -0
  171. package/dist/test/mergeTreeOperationRunner.spec.js +156 -0
  172. package/dist/test/mergeTreeOperationRunner.spec.js.map +1 -0
  173. package/dist/test/obliterate.concurrent.spec.d.ts +6 -0
  174. package/dist/test/obliterate.concurrent.spec.d.ts.map +1 -0
  175. package/dist/test/obliterate.concurrent.spec.js +1446 -0
  176. package/dist/test/obliterate.concurrent.spec.js.map +1 -0
  177. package/dist/test/obliterate.partialLength.spec.d.ts +6 -0
  178. package/dist/test/obliterate.partialLength.spec.d.ts.map +1 -0
  179. package/dist/test/obliterate.partialLength.spec.js +279 -0
  180. package/dist/test/obliterate.partialLength.spec.js.map +1 -0
  181. package/dist/test/obliterate.reconnect.spec.d.ts +6 -0
  182. package/dist/test/obliterate.reconnect.spec.d.ts.map +1 -0
  183. package/dist/test/obliterate.reconnect.spec.js +164 -0
  184. package/dist/test/obliterate.reconnect.spec.js.map +1 -0
  185. package/dist/test/obliterate.spec.d.ts +6 -0
  186. package/dist/test/obliterate.spec.d.ts.map +1 -0
  187. package/dist/test/obliterate.spec.js +162 -0
  188. package/dist/test/obliterate.spec.js.map +1 -0
  189. package/dist/test/ordinal.spec.d.ts +2 -0
  190. package/dist/test/ordinal.spec.d.ts.map +1 -0
  191. package/dist/test/ordinal.spec.js +43 -0
  192. package/dist/test/ordinal.spec.js.map +1 -0
  193. package/dist/test/partialLength.spec.d.ts +6 -0
  194. package/dist/test/partialLength.spec.d.ts.map +1 -0
  195. package/dist/test/partialLength.spec.js +282 -0
  196. package/dist/test/partialLength.spec.js.map +1 -0
  197. package/dist/test/properties.spec.d.ts +6 -0
  198. package/dist/test/properties.spec.d.ts.map +1 -0
  199. package/dist/test/properties.spec.js +55 -0
  200. package/dist/test/properties.spec.js.map +1 -0
  201. package/dist/test/reconnectHelper.d.ts +48 -0
  202. package/dist/test/reconnectHelper.d.ts.map +1 -0
  203. package/dist/test/reconnectHelper.js +86 -0
  204. package/dist/test/reconnectHelper.js.map +1 -0
  205. package/dist/test/resetPendingSegmentsToOp.spec.d.ts +6 -0
  206. package/dist/test/resetPendingSegmentsToOp.spec.d.ts.map +1 -0
  207. package/dist/test/resetPendingSegmentsToOp.spec.js +218 -0
  208. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -0
  209. package/dist/test/revertibleFarm.spec.d.ts +6 -0
  210. package/dist/test/revertibleFarm.spec.d.ts.map +1 -0
  211. package/dist/test/revertibleFarm.spec.js +124 -0
  212. package/dist/test/revertibleFarm.spec.js.map +1 -0
  213. package/dist/test/revertibles.spec.d.ts +17 -0
  214. package/dist/test/revertibles.spec.d.ts.map +1 -0
  215. package/dist/test/revertibles.spec.js +385 -0
  216. package/dist/test/revertibles.spec.js.map +1 -0
  217. package/dist/test/segmentGroupCollection.spec.d.ts +6 -0
  218. package/dist/test/segmentGroupCollection.spec.d.ts.map +1 -0
  219. package/dist/test/segmentGroupCollection.spec.js +60 -0
  220. package/dist/test/segmentGroupCollection.spec.js.map +1 -0
  221. package/dist/test/snapshot.spec.d.ts +6 -0
  222. package/dist/test/snapshot.spec.d.ts.map +1 -0
  223. package/dist/test/snapshot.spec.js +178 -0
  224. package/dist/test/snapshot.spec.js.map +1 -0
  225. package/dist/test/snapshot.utils.d.ts +33 -0
  226. package/dist/test/snapshot.utils.d.ts.map +1 -0
  227. package/dist/test/snapshot.utils.js +109 -0
  228. package/dist/test/snapshot.utils.js.map +1 -0
  229. package/dist/test/snapshotlegacy.spec.d.ts +6 -0
  230. package/dist/test/snapshotlegacy.spec.d.ts.map +1 -0
  231. package/dist/test/snapshotlegacy.spec.js +139 -0
  232. package/dist/test/snapshotlegacy.spec.js.map +1 -0
  233. package/dist/test/sortedSegmentSet.spec.d.ts +6 -0
  234. package/dist/test/sortedSegmentSet.spec.d.ts.map +1 -0
  235. package/dist/test/sortedSegmentSet.spec.js +95 -0
  236. package/dist/test/sortedSegmentSet.spec.js.map +1 -0
  237. package/dist/test/testClient.d.ts +119 -0
  238. package/dist/test/testClient.d.ts.map +1 -0
  239. package/dist/test/testClient.js +439 -0
  240. package/dist/test/testClient.js.map +1 -0
  241. package/dist/test/testClientLogger.d.ts +44 -0
  242. package/dist/test/testClientLogger.d.ts.map +1 -0
  243. package/dist/test/testClientLogger.js +287 -0
  244. package/dist/test/testClientLogger.js.map +1 -0
  245. package/dist/test/testSerializer.d.ts +18 -0
  246. package/dist/test/testSerializer.d.ts.map +1 -0
  247. package/dist/test/testSerializer.js +33 -0
  248. package/dist/test/testSerializer.js.map +1 -0
  249. package/dist/test/testServer.d.ts +36 -0
  250. package/dist/test/testServer.d.ts.map +1 -0
  251. package/dist/test/testServer.js +138 -0
  252. package/dist/test/testServer.js.map +1 -0
  253. package/dist/test/testUtils.d.ts +69 -0
  254. package/dist/test/testUtils.d.ts.map +1 -0
  255. package/dist/test/testUtils.js +149 -0
  256. package/dist/test/testUtils.js.map +1 -0
  257. package/dist/test/text.d.ts +9 -0
  258. package/dist/test/text.d.ts.map +1 -0
  259. package/dist/test/text.js +76 -0
  260. package/dist/test/text.js.map +1 -0
  261. package/dist/test/tracking.spec.d.ts +6 -0
  262. package/dist/test/tracking.spec.d.ts.map +1 -0
  263. package/dist/test/tracking.spec.js +120 -0
  264. package/dist/test/tracking.spec.js.map +1 -0
  265. package/dist/test/wordUnitTests.d.ts +6 -0
  266. package/dist/test/wordUnitTests.d.ts.map +1 -0
  267. package/dist/test/wordUnitTests.js +172 -0
  268. package/dist/test/wordUnitTests.js.map +1 -0
  269. package/lib/{MergeTreeTextHelper.d.ts → MergeTreeTextHelper.d.mts} +3 -3
  270. package/lib/MergeTreeTextHelper.d.mts.map +1 -0
  271. package/lib/{MergeTreeTextHelper.js → MergeTreeTextHelper.mjs} +5 -10
  272. package/lib/MergeTreeTextHelper.mjs.map +1 -0
  273. package/lib/{attributionCollection.d.ts → attributionCollection.d.mts} +2 -2
  274. package/lib/attributionCollection.d.mts.map +1 -0
  275. package/lib/{attributionCollection.js → attributionCollection.mjs} +9 -14
  276. package/lib/attributionCollection.mjs.map +1 -0
  277. package/lib/{attributionPolicy.d.ts → attributionPolicy.d.mts} +2 -2
  278. package/lib/attributionPolicy.d.mts.map +1 -0
  279. package/lib/{attributionPolicy.js → attributionPolicy.mjs} +21 -27
  280. package/lib/attributionPolicy.mjs.map +1 -0
  281. package/lib/{client.d.ts → client.d.mts} +9 -16
  282. package/lib/client.d.mts.map +1 -0
  283. package/lib/{client.js → client.mjs} +101 -110
  284. package/lib/client.mjs.map +1 -0
  285. package/lib/collections/{index.d.ts → index.d.mts} +3 -3
  286. package/lib/collections/index.d.mts.map +1 -0
  287. package/lib/collections/index.mjs +7 -0
  288. package/lib/collections/index.mjs.map +1 -0
  289. package/lib/collections/{list.d.ts → list.d.mts} +1 -1
  290. package/lib/collections/list.d.mts.map +1 -0
  291. package/lib/collections/{list.js → list.mjs} +6 -11
  292. package/lib/collections/list.mjs.map +1 -0
  293. package/lib/collections/{rbTree.d.ts → rbTree.d.mts} +1 -1
  294. package/lib/collections/rbTree.d.mts.map +1 -0
  295. package/lib/collections/{rbTree.js → rbTree.mjs} +16 -20
  296. package/lib/collections/rbTree.mjs.map +1 -0
  297. package/lib/{constants.d.ts → constants.d.mts} +1 -1
  298. package/lib/constants.d.mts.map +1 -0
  299. package/lib/constants.mjs +32 -0
  300. package/lib/constants.mjs.map +1 -0
  301. package/lib/{endOfTreeSegment.d.ts → endOfTreeSegment.d.mts} +4 -4
  302. package/lib/endOfTreeSegment.d.mts.map +1 -0
  303. package/lib/{endOfTreeSegment.js → endOfTreeSegment.mjs} +13 -18
  304. package/lib/endOfTreeSegment.mjs.map +1 -0
  305. package/lib/{index.d.ts → index.d.mts} +21 -21
  306. package/lib/index.d.mts.map +1 -0
  307. package/lib/index.mjs +24 -0
  308. package/lib/index.mjs.map +1 -0
  309. package/lib/{localReference.d.ts → localReference.d.mts} +7 -7
  310. package/lib/localReference.d.mts.map +1 -0
  311. package/lib/{localReference.js → localReference.mjs} +38 -47
  312. package/lib/localReference.mjs.map +1 -0
  313. package/lib/{merge-tree-alpha.d.ts → merge-tree-alpha.d.mts} +27 -12
  314. package/lib/{merge-tree-beta.d.ts → merge-tree-beta.d.mts} +0 -16
  315. package/lib/{merge-tree-public.d.ts → merge-tree-public.d.mts} +0 -16
  316. package/lib/{merge-tree-untrimmed.d.ts → merge-tree-untrimmed.d.mts} +5 -29
  317. package/lib/{mergeTree.d.ts → mergeTree.d.mts} +12 -29
  318. package/lib/mergeTree.d.mts.map +1 -0
  319. package/lib/{mergeTree.js → mergeTree.mjs} +203 -340
  320. package/lib/mergeTree.mjs.map +1 -0
  321. package/lib/{mergeTreeDeltaCallback.d.ts → mergeTreeDeltaCallback.d.mts} +4 -8
  322. package/lib/mergeTreeDeltaCallback.d.mts.map +1 -0
  323. package/lib/{mergeTreeDeltaCallback.js → mergeTreeDeltaCallback.mjs} +2 -5
  324. package/lib/mergeTreeDeltaCallback.mjs.map +1 -0
  325. package/lib/{mergeTreeNodeWalk.d.ts → mergeTreeNodeWalk.d.mts} +2 -2
  326. package/lib/mergeTreeNodeWalk.d.mts.map +1 -0
  327. package/lib/{mergeTreeNodeWalk.js → mergeTreeNodeWalk.mjs} +14 -21
  328. package/lib/mergeTreeNodeWalk.mjs.map +1 -0
  329. package/lib/{mergeTreeNodes.d.ts → mergeTreeNodes.d.mts} +12 -12
  330. package/lib/mergeTreeNodes.d.mts.map +1 -0
  331. package/lib/{mergeTreeNodes.js → mergeTreeNodes.mjs} +60 -76
  332. package/lib/mergeTreeNodes.mjs.map +1 -0
  333. package/lib/{mergeTreeTracking.d.ts → mergeTreeTracking.d.mts} +3 -3
  334. package/lib/mergeTreeTracking.d.mts.map +1 -0
  335. package/lib/{mergeTreeTracking.js → mergeTreeTracking.mjs} +6 -13
  336. package/lib/mergeTreeTracking.mjs.map +1 -0
  337. package/lib/{opBuilder.d.ts → opBuilder.d.mts} +4 -4
  338. package/lib/opBuilder.d.mts.map +1 -0
  339. package/lib/{opBuilder.js → opBuilder.mjs} +15 -25
  340. package/lib/opBuilder.mjs.map +1 -0
  341. package/lib/{ops.d.ts → ops.d.mts} +2 -2
  342. package/lib/ops.d.mts.map +1 -0
  343. package/lib/{ops.js → ops.mjs} +5 -8
  344. package/lib/ops.mjs.map +1 -0
  345. package/lib/{ordinal.d.ts → ordinal.d.mts} +1 -1
  346. package/lib/ordinal.d.mts.map +1 -0
  347. package/lib/{ordinal.js → ordinal.mjs} +4 -9
  348. package/lib/ordinal.mjs.map +1 -0
  349. package/lib/{partialLengths.d.ts → partialLengths.d.mts} +4 -4
  350. package/lib/partialLengths.d.mts.map +1 -0
  351. package/lib/{partialLengths.js → partialLengths.mjs} +38 -46
  352. package/lib/partialLengths.mjs.map +1 -0
  353. package/lib/{properties.d.ts → properties.d.mts} +1 -1
  354. package/lib/properties.d.mts.map +1 -0
  355. package/lib/{properties.js → properties.mjs} +7 -16
  356. package/lib/properties.mjs.map +1 -0
  357. package/lib/{referencePositions.d.ts → referencePositions.d.mts} +5 -5
  358. package/lib/referencePositions.d.mts.map +1 -0
  359. package/lib/referencePositions.mjs +70 -0
  360. package/lib/referencePositions.mjs.map +1 -0
  361. package/lib/{revertibles.d.ts → revertibles.d.mts} +12 -12
  362. package/lib/revertibles.d.mts.map +1 -0
  363. package/lib/{revertibles.js → revertibles.mjs} +60 -67
  364. package/lib/revertibles.mjs.map +1 -0
  365. package/lib/{segmentGroupCollection.d.ts → segmentGroupCollection.d.mts} +2 -2
  366. package/lib/segmentGroupCollection.d.mts.map +1 -0
  367. package/lib/{segmentGroupCollection.js → segmentGroupCollection.mjs} +5 -9
  368. package/lib/segmentGroupCollection.mjs.map +1 -0
  369. package/lib/{segmentPropertiesManager.d.ts → segmentPropertiesManager.d.mts} +3 -3
  370. package/lib/segmentPropertiesManager.d.mts.map +1 -0
  371. package/lib/{segmentPropertiesManager.js → segmentPropertiesManager.mjs} +14 -20
  372. package/lib/{segmentPropertiesManager.js.map → segmentPropertiesManager.mjs.map} +1 -1
  373. package/lib/{snapshotChunks.d.ts → snapshotChunks.d.mts} +4 -4
  374. package/lib/snapshotChunks.d.mts.map +1 -0
  375. package/lib/{snapshotChunks.js → snapshotChunks.mjs} +10 -17
  376. package/lib/snapshotChunks.mjs.map +1 -0
  377. package/lib/{snapshotLoader.d.ts → snapshotLoader.d.mts} +3 -3
  378. package/lib/snapshotLoader.d.mts.map +1 -0
  379. package/lib/{snapshotLoader.js → snapshotLoader.mjs} +33 -38
  380. package/lib/snapshotLoader.mjs.map +1 -0
  381. package/lib/{snapshotV1.d.ts → snapshotV1.d.mts} +4 -4
  382. package/lib/snapshotV1.d.mts.map +1 -0
  383. package/lib/{snapshotV1.js → snapshotV1.mjs} +28 -32
  384. package/lib/snapshotV1.mjs.map +1 -0
  385. package/lib/{snapshotlegacy.d.ts → snapshotlegacy.d.mts} +3 -3
  386. package/lib/snapshotlegacy.d.mts.map +1 -0
  387. package/lib/{snapshotlegacy.js → snapshotlegacy.mjs} +21 -26
  388. package/lib/snapshotlegacy.mjs.map +1 -0
  389. package/lib/{sortedSegmentSet.d.ts → sortedSegmentSet.d.mts} +4 -4
  390. package/lib/sortedSegmentSet.d.mts.map +1 -0
  391. package/lib/{sortedSegmentSet.js → sortedSegmentSet.mjs} +3 -8
  392. package/lib/sortedSegmentSet.mjs.map +1 -0
  393. package/lib/{sortedSet.d.ts → sortedSet.d.mts} +1 -1
  394. package/lib/sortedSet.d.mts.map +1 -0
  395. package/lib/{sortedSet.js → sortedSet.mjs} +2 -6
  396. package/lib/sortedSet.mjs.map +1 -0
  397. package/lib/{textSegment.d.ts → textSegment.d.mts} +4 -4
  398. package/lib/textSegment.d.mts.map +1 -0
  399. package/lib/{textSegment.js → textSegment.mjs} +8 -12
  400. package/lib/textSegment.mjs.map +1 -0
  401. package/lib/{zamboni.d.ts → zamboni.d.mts} +3 -3
  402. package/lib/zamboni.d.mts.map +1 -0
  403. package/lib/{zamboni.js → zamboni.mjs} +22 -28
  404. package/lib/zamboni.mjs.map +1 -0
  405. package/package.json +95 -164
  406. package/src/client.ts +0 -8
  407. package/src/mergeTree.ts +0 -226
  408. package/src/ops.ts +1 -1
  409. package/src/revertibles.ts +4 -4
  410. package/lib/MergeTreeTextHelper.d.ts.map +0 -1
  411. package/lib/MergeTreeTextHelper.js.map +0 -1
  412. package/lib/attributionCollection.d.ts.map +0 -1
  413. package/lib/attributionCollection.js.map +0 -1
  414. package/lib/attributionPolicy.d.ts.map +0 -1
  415. package/lib/attributionPolicy.js.map +0 -1
  416. package/lib/client.d.ts.map +0 -1
  417. package/lib/client.js.map +0 -1
  418. package/lib/collections/index.d.ts.map +0 -1
  419. package/lib/collections/index.js +0 -14
  420. package/lib/collections/index.js.map +0 -1
  421. package/lib/collections/list.d.ts.map +0 -1
  422. package/lib/collections/list.js.map +0 -1
  423. package/lib/collections/rbTree.d.ts.map +0 -1
  424. package/lib/collections/rbTree.js.map +0 -1
  425. package/lib/constants.d.ts.map +0 -1
  426. package/lib/constants.js +0 -35
  427. package/lib/constants.js.map +0 -1
  428. package/lib/endOfTreeSegment.d.ts.map +0 -1
  429. package/lib/endOfTreeSegment.js.map +0 -1
  430. package/lib/index.d.ts.map +0 -1
  431. package/lib/index.js +0 -80
  432. package/lib/index.js.map +0 -1
  433. package/lib/localReference.d.ts.map +0 -1
  434. package/lib/localReference.js.map +0 -1
  435. package/lib/mergeTree.d.ts.map +0 -1
  436. package/lib/mergeTree.js.map +0 -1
  437. package/lib/mergeTreeDeltaCallback.d.ts.map +0 -1
  438. package/lib/mergeTreeDeltaCallback.js.map +0 -1
  439. package/lib/mergeTreeNodeWalk.d.ts.map +0 -1
  440. package/lib/mergeTreeNodeWalk.js.map +0 -1
  441. package/lib/mergeTreeNodes.d.ts.map +0 -1
  442. package/lib/mergeTreeNodes.js.map +0 -1
  443. package/lib/mergeTreeTracking.d.ts.map +0 -1
  444. package/lib/mergeTreeTracking.js.map +0 -1
  445. package/lib/opBuilder.d.ts.map +0 -1
  446. package/lib/opBuilder.js.map +0 -1
  447. package/lib/ops.d.ts.map +0 -1
  448. package/lib/ops.js.map +0 -1
  449. package/lib/ordinal.d.ts.map +0 -1
  450. package/lib/ordinal.js.map +0 -1
  451. package/lib/partialLengths.d.ts.map +0 -1
  452. package/lib/partialLengths.js.map +0 -1
  453. package/lib/properties.d.ts.map +0 -1
  454. package/lib/properties.js.map +0 -1
  455. package/lib/referencePositions.d.ts.map +0 -1
  456. package/lib/referencePositions.js +0 -80
  457. package/lib/referencePositions.js.map +0 -1
  458. package/lib/revertibles.d.ts.map +0 -1
  459. package/lib/revertibles.js.map +0 -1
  460. package/lib/segmentGroupCollection.d.ts.map +0 -1
  461. package/lib/segmentGroupCollection.js.map +0 -1
  462. package/lib/segmentPropertiesManager.d.ts.map +0 -1
  463. package/lib/snapshotChunks.d.ts.map +0 -1
  464. package/lib/snapshotChunks.js.map +0 -1
  465. package/lib/snapshotLoader.d.ts.map +0 -1
  466. package/lib/snapshotLoader.js.map +0 -1
  467. package/lib/snapshotV1.d.ts.map +0 -1
  468. package/lib/snapshotV1.js.map +0 -1
  469. package/lib/snapshotlegacy.d.ts.map +0 -1
  470. package/lib/snapshotlegacy.js.map +0 -1
  471. package/lib/sortedSegmentSet.d.ts.map +0 -1
  472. package/lib/sortedSegmentSet.js.map +0 -1
  473. package/lib/sortedSet.d.ts.map +0 -1
  474. package/lib/sortedSet.js.map +0 -1
  475. package/lib/textSegment.d.ts.map +0 -1
  476. package/lib/textSegment.js.map +0 -1
  477. package/lib/zamboni.d.ts.map +0 -1
  478. package/lib/zamboni.js.map +0 -1
  479. package/merge-tree.test-files.tar +0 -0
  480. package/src/mergeTreeExample1.pdf +0 -0
  481. package/tsconfig.esnext.json +0 -6
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const assert_1 = require("assert");
9
+ const mergeTreeNodes_1 = require("../mergeTreeNodes");
10
+ const ops_1 = require("../ops");
11
+ const properties_1 = require("../properties");
12
+ const textSegment_1 = require("../textSegment");
13
+ const testClient_1 = require("./testClient");
14
+ describe("resetPendingSegmentsToOp", () => {
15
+ let client;
16
+ beforeEach(() => {
17
+ client = new testClient_1.TestClient();
18
+ client.startOrUpdateCollaboration("local user");
19
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
20
+ });
21
+ describe("with a number of nested inserts", () => {
22
+ const insertCount = 5;
23
+ const expectedSegmentCount = insertCount * 2 - 1;
24
+ let opList;
25
+ let opCount = 0;
26
+ function applyOpList(cli) {
27
+ while (opList.length > 0) {
28
+ const op = opList.shift();
29
+ if (op) {
30
+ const seqOp = cli.makeOpMessage(op.op, ++opCount, op.refSeq);
31
+ cli.applyMsg(seqOp);
32
+ }
33
+ }
34
+ }
35
+ beforeEach(() => {
36
+ opList = [];
37
+ opCount = 0;
38
+ for (let i = 0; i < insertCount; i++) {
39
+ const op = client.insertTextLocal(i, "hello");
40
+ opList.push({ op, refSeq: client.getCurrentSeq() });
41
+ assert_1.strict.equal(client.mergeTree.pendingSegments?.length, i + 1);
42
+ }
43
+ });
44
+ it("acked insertSegment", async () => {
45
+ applyOpList(client);
46
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
47
+ });
48
+ it("only computes localPartialLengths once", () => {
49
+ // This test helps verify the asymptotic correctness of rebase.
50
+ // Since local partial length information is reasonably expensive to store and compute compared to how
51
+ // frequently it's used (i.e. only on reconnect), mergeTree has some logic to only do so when requested,
52
+ // and invalidates that info whenever a segment update occurs.
53
+ // This test verifies that local partial length information only gets computed once when regenerating
54
+ // a number of ops for reconnection.
55
+ let localPartialsComputeCount = 0;
56
+ const spiedMergeTree = client.mergeTree;
57
+ spiedMergeTree._localPartialsComputed = spiedMergeTree.localPartialsComputed;
58
+ Object.defineProperty(client.mergeTree, "localPartialsComputed", {
59
+ get() {
60
+ return this._localPartialsComputed;
61
+ },
62
+ set(newValue) {
63
+ if (newValue) {
64
+ localPartialsComputeCount++;
65
+ }
66
+ this._localPartialsComputed = newValue;
67
+ },
68
+ });
69
+ const oldops = opList;
70
+ const pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];
71
+ opList = oldops.map((op) => ({
72
+ op: client.regeneratePendingOp(op.op, pending.shift()),
73
+ refSeq: client.getCurrentSeq(),
74
+ }));
75
+ applyOpList(client);
76
+ assert_1.strict.equal(localPartialsComputeCount, 1);
77
+ });
78
+ it("nacked insertSegment", async () => {
79
+ const oldops = opList;
80
+ const pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];
81
+ opList = oldops.map((op) => ({
82
+ op: client.regeneratePendingOp(op.op, pending.shift()),
83
+ refSeq: client.getCurrentSeq(),
84
+ }));
85
+ // we expect a nack op per segment since our original ops split segments
86
+ // we should expect mores nack ops then original ops.
87
+ // only the first op didn't split a segment, all the others did
88
+ assert_1.strict.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);
89
+ applyOpList(client);
90
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
91
+ });
92
+ it("acked removeRange", async () => {
93
+ applyOpList(client);
94
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
95
+ opList.push({
96
+ op: client.removeRangeLocal(0, client.getLength()),
97
+ refSeq: client.getCurrentSeq(),
98
+ });
99
+ applyOpList(client);
100
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
101
+ });
102
+ it("nacked removeRange", async () => {
103
+ applyOpList(client);
104
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
105
+ opList.push({
106
+ op: client.removeRangeLocal(0, client.getLength()),
107
+ refSeq: client.getCurrentSeq(),
108
+ });
109
+ opList.push({
110
+ op: client.regeneratePendingOp(opList.shift().op, client.mergeTree.pendingSegments.first.data),
111
+ refSeq: client.getCurrentSeq(),
112
+ });
113
+ // we expect a nack op per segment since our original ops split segments
114
+ // we should expect mores nack ops then original ops.
115
+ // only the first op didn't split a segment, all the others did
116
+ assert_1.strict.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);
117
+ applyOpList(client);
118
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
119
+ });
120
+ it("nacked insertSegment and removeRange", async () => {
121
+ opList.push({
122
+ op: client.removeRangeLocal(0, client.getLength()),
123
+ refSeq: client.getCurrentSeq(),
124
+ });
125
+ const oldops = opList;
126
+ const pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];
127
+ opList = oldops.map((op) => ({
128
+ op: client.regeneratePendingOp(op.op, pending.shift()),
129
+ refSeq: client.getCurrentSeq(),
130
+ }));
131
+ assert_1.strict.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount * 2);
132
+ applyOpList(client);
133
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
134
+ });
135
+ it("acked annotateRange", async () => {
136
+ applyOpList(client);
137
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
138
+ opList.push({
139
+ op: client.annotateRangeLocal(0, client.getLength(), { foo: "bar" }),
140
+ refSeq: client.getCurrentSeq(),
141
+ });
142
+ applyOpList(client);
143
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
144
+ });
145
+ it("nacked annotateRange", async () => {
146
+ applyOpList(client);
147
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
148
+ opList.push({
149
+ op: client.annotateRangeLocal(0, client.getLength(), { foo: "bar" }),
150
+ refSeq: client.getCurrentSeq(),
151
+ });
152
+ opList.push({
153
+ op: client.regeneratePendingOp(opList.shift().op, client.mergeTree.pendingSegments.first.data),
154
+ refSeq: client.getCurrentSeq(),
155
+ });
156
+ // we expect a nack op per segment since our original ops split segments
157
+ // we should expect mores nack ops then original ops.
158
+ // only the first op didn't split a segment, all the others did
159
+ assert_1.strict.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount);
160
+ applyOpList(client);
161
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
162
+ });
163
+ it("nacked insertSegment and annotateRange", async () => {
164
+ opList.push({
165
+ op: client.annotateRangeLocal(0, client.getLength(), { foo: "bar" }),
166
+ refSeq: client.getCurrentSeq(),
167
+ });
168
+ const oldops = opList;
169
+ const pending = [...client.mergeTree.pendingSegments.map((n) => n.data)];
170
+ opList = oldops.map((op) => ({
171
+ op: client.regeneratePendingOp(op.op, pending.shift()),
172
+ refSeq: client.getCurrentSeq(),
173
+ }));
174
+ // we expect a nack op per segment since our original ops split segments
175
+ // we should expect mores nack ops then original ops.
176
+ // only the first op didn't split a segment, all the others did
177
+ assert_1.strict.equal(client.mergeTree.pendingSegments?.length, expectedSegmentCount * 2);
178
+ applyOpList(client);
179
+ (0, assert_1.strict)(client.mergeTree.pendingSegments?.empty);
180
+ });
181
+ });
182
+ describe("uses original properties on insert", () => {
183
+ // Regression tests for an issue where regenerated insert ops would use the properties of a segment
184
+ // at the time of regeneration rather than its properties at insertion time.
185
+ it("for markers", () => {
186
+ const insertOp = client.insertMarkerLocal(0, ops_1.ReferenceType.Simple, {
187
+ [mergeTreeNodes_1.reservedMarkerIdKey]: "id",
188
+ prop1: "foo",
189
+ });
190
+ (0, assert_1.strict)(insertOp);
191
+ const { segment } = client.getContainingSegment(0);
192
+ (0, assert_1.strict)(segment !== undefined && mergeTreeNodes_1.Marker.is(segment));
193
+ client.annotateMarker(segment, { prop2: "bar" });
194
+ const otherClient = new testClient_1.TestClient();
195
+ otherClient.startOrUpdateCollaboration("other user");
196
+ const regeneratedInsert = client.regeneratePendingOp(insertOp, client.mergeTree.pendingSegments.first.data);
197
+ otherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);
198
+ const { segment: otherSegment } = otherClient.getContainingSegment(0);
199
+ (0, assert_1.strict)(otherSegment !== undefined && mergeTreeNodes_1.Marker.is(otherSegment));
200
+ // `clone` here is because properties use a Object.create(null); to compare strict equal the prototype chain
201
+ // should therefore not include Object.
202
+ assert_1.strict.deepStrictEqual(otherSegment.properties, (0, properties_1.clone)({ [mergeTreeNodes_1.reservedMarkerIdKey]: "id", prop1: "foo" }));
203
+ });
204
+ it("for text segments", () => {
205
+ const insertOp = client.insertTextLocal(0, "abc", { prop1: "foo" });
206
+ (0, assert_1.strict)(insertOp);
207
+ client.annotateRangeLocal(0, 3, { prop2: "bar" });
208
+ const otherClient = new testClient_1.TestClient();
209
+ otherClient.startOrUpdateCollaboration("other user");
210
+ const regeneratedInsert = client.regeneratePendingOp(insertOp, client.mergeTree.pendingSegments.first.data);
211
+ otherClient.applyMsg(client.makeOpMessage(regeneratedInsert, 1), false);
212
+ const { segment: otherSegment } = otherClient.getContainingSegment(0);
213
+ (0, assert_1.strict)(otherSegment !== undefined && textSegment_1.TextSegment.is(otherSegment));
214
+ assert_1.strict.deepStrictEqual(otherSegment.properties, (0, properties_1.clone)({ prop1: "foo" }));
215
+ });
216
+ });
217
+ });
218
+ //# sourceMappingURL=resetPendingSegmentsToOp.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resetPendingSegmentsToOp.spec.js","sourceRoot":"","sources":["../../src/test/resetPendingSegmentsToOp.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;AACH,6DAA6D;;AAE7D,mCAA0C;AAC1C,sDAAgE;AAChE,gCAAqD;AACrD,8CAAsC;AACtC,gDAA6C;AAC7C,6CAA0C;AAE1C,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACzC,IAAI,MAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,IAAI,uBAAU,EAAE,CAAC;QAC1B,MAAM,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,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;gBACzB,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,EAAE,EAAE;oBACP,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;iBACpB;aACD;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;gBACrC,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,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;aAC9D;QACF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACpC,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,IAAA,eAAM,EAAC,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,OAAO,IAAI,CAAC,sBAAiC,CAAC;gBAC/C,CAAC;gBACD,GAAG,CAAC,QAAQ;oBACX,IAAI,QAAQ,EAAE;wBACb,yBAAyB,EAAE,CAAC;qBAC5B;oBACD,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,eAAM,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,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAC7E,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,IAAA,eAAM,EAAC,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,IAAA,eAAM,EAAC,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,IAAA,eAAM,EAAC,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,IAAA,eAAM,EAAC,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,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,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAC7E,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,IAAA,eAAM,EAAC,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,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,CAAC,CAAC;YAEjF,WAAW,CAAC,MAAM,CAAC,CAAC;YAEpB,IAAA,eAAM,EAAC,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,IAAA,eAAM,EAAC,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,IAAA,eAAM,EAAC,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,IAAA,eAAM,EAAC,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,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,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAC7E,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,IAAA,eAAM,EAAC,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,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,CAAC,CAAC;YACjF,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,IAAA,eAAM,EAAC,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,mBAAa,CAAC,MAAM,EAAE;gBAClE,CAAC,oCAAmB,CAAC,EAAE,IAAI;gBAC3B,KAAK,EAAE,KAAK;aACZ,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC;YACjB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YACnD,IAAA,eAAM,EAAC,OAAO,KAAK,SAAS,IAAI,uBAAM,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,uBAAU,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,CAAC,CAAC,CAAC,CAAC;YACtE,IAAA,eAAM,EAAC,YAAY,KAAK,SAAS,IAAI,uBAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YAC9D,4GAA4G;YAC5G,uCAAuC;YACvC,eAAM,CAAC,eAAe,CACrB,YAAY,CAAC,UAAU,EACvB,IAAA,kBAAK,EAAC,EAAE,CAAC,oCAAmB,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,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC;YACjB,MAAM,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAElD,MAAM,WAAW,GAAG,IAAI,uBAAU,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,CAAC,CAAC,CAAC,CAAC;YACtE,IAAA,eAAM,EAAC,YAAY,KAAK,SAAS,IAAI,yBAAW,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YACnE,eAAM,CAAC,eAAe,CAAC,YAAY,CAAC,UAAU,EAAE,IAAA,kBAAK,EAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACJ,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/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"assert\";\nimport { Marker, reservedMarkerIdKey } from \"../mergeTreeNodes\";\nimport { IMergeTreeOp, ReferenceType } from \"../ops\";\nimport { clone } from \"../properties\";\nimport { TextSegment } from \"../textSegment\";\nimport { TestClient } from \"./testClient\";\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) {\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\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\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\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\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(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(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(0);\n\t\t\tassert(otherSegment !== undefined && TextSegment.is(otherSegment));\n\t\t\tassert.deepStrictEqual(otherSegment.properties, clone({ prop1: \"foo\" }));\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=revertibleFarm.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertibleFarm.spec.d.ts","sourceRoot":"","sources":["../../src/test/revertibleFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const assert_1 = __importDefault(require("assert"));
11
+ const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
12
+ const revertibles_1 = require("../revertibles");
13
+ const mergeTreeNodeWalk_1 = require("../mergeTreeNodeWalk");
14
+ const mergeTreeOperationRunner_1 = require("./mergeTreeOperationRunner");
15
+ const testClient_1 = require("./testClient");
16
+ const testClientLogger_1 = require("./testClientLogger");
17
+ const defaultOptions = {
18
+ initialOps: 5,
19
+ minLength: { min: 1, max: 256, growthFunc: (i) => i * i },
20
+ concurrentOpsWithRevert: { min: 0, max: 8 },
21
+ revertOps: { min: 1, max: 16 },
22
+ ackBeforeRevert: ["None", "Some", "All"],
23
+ rounds: 10,
24
+ operations: [mergeTreeOperationRunner_1.removeRange, mergeTreeOperationRunner_1.annotateRange],
25
+ growthFunc: (i) => i * 2,
26
+ };
27
+ describe("MergeTree.Client", () => {
28
+ (0, mergeTreeOperationRunner_1.doOverRanges)(defaultOptions, ({ minLength: minLen, concurrentOpsWithRevert, revertOps }) => {
29
+ for (const ackBeforeRevert of defaultOptions.ackBeforeRevert) {
30
+ it(`InitialOps: ${defaultOptions.initialOps} MinLen: ${minLen} ConcurrentOpsWithRevert: ${concurrentOpsWithRevert} RevertOps: ${revertOps} AckBeforeRevert: ${ackBeforeRevert}`, async () => {
31
+ const random = (0, stochastic_test_utils_1.makeRandom)(minLen, revertOps, [...ackBeforeRevert].reduce((pv, cv) => pv + cv.charCodeAt(0), 0), concurrentOpsWithRevert);
32
+ const clients = (0, testClientLogger_1.createClientsAtInitialState)({
33
+ initialState: "",
34
+ options: {},
35
+ }, "A", "B", "C");
36
+ let seq = 0;
37
+ for (let rnd = 0; rnd < defaultOptions.rounds; rnd++) {
38
+ clients.all.forEach((c) => c.updateMinSeq(seq));
39
+ const logger = new testClientLogger_1.TestClientLogger(clients.all, `Round ${rnd}`);
40
+ {
41
+ // init with random values
42
+ const initialMsgs = (0, mergeTreeOperationRunner_1.generateOperationMessagesForClients)(random, seq, clients.all, logger, defaultOptions.initialOps, minLen, defaultOptions.operations);
43
+ seq = (0, mergeTreeOperationRunner_1.applyMessages)(seq, initialMsgs, clients.all, logger);
44
+ }
45
+ // cache the base text to ensure we get back to it after revert
46
+ const undoBaseText = logger.validate({
47
+ clear: true,
48
+ errorPrefix: "After Initial Ops",
49
+ });
50
+ const clientB_Revertibles = [];
51
+ const clientBDriver = (0, testClient_1.createRevertDriver)(clients.B);
52
+ const deltaCallback = (op, delta) => {
53
+ if (op.sequencedMessage === undefined) {
54
+ (0, revertibles_1.appendToMergeTreeDeltaRevertibles)(delta, clientB_Revertibles);
55
+ }
56
+ };
57
+ const msgs = [];
58
+ {
59
+ clientBDriver.submitOpCallback = (op) => msgs.push([
60
+ clients.B.makeOpMessage(op, undefined, undefined, undefined, seq),
61
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
62
+ clients.B.peekPendingSegmentGroups(),
63
+ ]);
64
+ clients.B.on("delta", deltaCallback);
65
+ msgs.push(...(0, mergeTreeOperationRunner_1.generateOperationMessagesForClients)(random, seq, [clients.A, clients.B], logger, revertOps, minLen, defaultOptions.operations));
66
+ }
67
+ if (concurrentOpsWithRevert > 0) {
68
+ // add modifications from another client
69
+ msgs.push(...(0, mergeTreeOperationRunner_1.generateOperationMessagesForClients)(random, seq, [clients.A, clients.C], logger, concurrentOpsWithRevert, minLen, defaultOptions.operations));
70
+ }
71
+ let redoBaseText;
72
+ if (ackBeforeRevert !== "None") {
73
+ const ackAll = ackBeforeRevert === "All";
74
+ seq = (0, mergeTreeOperationRunner_1.applyMessages)(seq, msgs.splice(0, ackAll
75
+ ? msgs.length
76
+ : random.integer(0, Math.floor(msgs.length / 2))), clients.all, logger);
77
+ if (ackAll) {
78
+ redoBaseText = logger.validate({ errorPrefix: "Before Revert Ack" });
79
+ }
80
+ }
81
+ try {
82
+ (0, revertibles_1.revertMergeTreeDeltaRevertibles)(clientBDriver, clientB_Revertibles.splice(0));
83
+ seq = (0, mergeTreeOperationRunner_1.applyMessages)(seq, msgs.splice(0), clients.all, logger);
84
+ }
85
+ catch (e) {
86
+ throw logger.addLogsToError(e);
87
+ }
88
+ logger.validate({
89
+ clear: true,
90
+ baseText: concurrentOpsWithRevert === 0 ? undoBaseText : undefined,
91
+ errorPrefix: "After Revert (undo)",
92
+ });
93
+ try {
94
+ // reset the callback before the final revert
95
+ // to avoid accruing any new detached references
96
+ clients.B.off("delta", deltaCallback);
97
+ (0, revertibles_1.revertMergeTreeDeltaRevertibles)(clientBDriver, clientB_Revertibles.splice(0));
98
+ seq = (0, mergeTreeOperationRunner_1.applyMessages)(seq, msgs.splice(0), clients.all, logger);
99
+ (0, mergeTreeNodeWalk_1.walkAllChildSegments)(clients.B.mergeTree.root, (seg) => {
100
+ if (seg?.trackingCollection.empty === false) {
101
+ assert_1.default.notDeepStrictEqual(seg?.trackingCollection.empty, false, "there should be no left over tracking group");
102
+ }
103
+ if (seg?.localRefs?.empty === false) {
104
+ assert_1.default.notDeepStrictEqual(seg?.localRefs?.empty, false, "there should be no left over local references");
105
+ }
106
+ });
107
+ const mergeTreeWithRevert = clients.B.mergeTree;
108
+ assert_1.default.notDeepStrictEqual(mergeTreeWithRevert.__mergeTreeRevertible?.detachedReferences?.localRefs
109
+ ?.empty, false, "there should be no left over local references in detached references");
110
+ }
111
+ catch (e) {
112
+ throw logger.addLogsToError(e);
113
+ }
114
+ logger.validate({
115
+ errorPrefix: "After Re-Revert (redo)",
116
+ baseText: redoBaseText,
117
+ });
118
+ logger.dispose();
119
+ }
120
+ });
121
+ }
122
+ });
123
+ });
124
+ //# sourceMappingURL=revertibleFarm.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertibleFarm.spec.js","sourceRoot":"","sources":["../../src/test/revertibleFarm.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 assert from \"assert\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISegment, SegmentGroup } from \"../mergeTreeNodes\";\nimport {\n\tappendToMergeTreeDeltaRevertibles,\n\tMergeTreeDeltaRevertible,\n\tMergeTreeWithRevert,\n\trevertMergeTreeDeltaRevertibles,\n} from \"../revertibles\";\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk\";\nimport {\n\tremoveRange,\n\tgenerateOperationMessagesForClients,\n\tapplyMessages,\n\tannotateRange,\n\tdoOverRanges,\n} from \"./mergeTreeOperationRunner\";\nimport { createRevertDriver } from \"./testClient\";\nimport { createClientsAtInitialState, TestClientLogger } from \"./testClientLogger\";\n\nconst defaultOptions = {\n\tinitialOps: 5,\n\tminLength: { min: 1, max: 256, growthFunc: (i) => i * i },\n\tconcurrentOpsWithRevert: { min: 0, max: 8 },\n\trevertOps: { min: 1, max: 16 },\n\tackBeforeRevert: [\"None\", \"Some\", \"All\"] as (\"None\" | \"Some\" | \"All\")[],\n\trounds: 10,\n\toperations: [removeRange, annotateRange],\n\tgrowthFunc: (i) => i * 2,\n};\n\ndescribe(\"MergeTree.Client\", () => {\n\tdoOverRanges(defaultOptions, ({ minLength: minLen, concurrentOpsWithRevert, revertOps }) => {\n\t\tfor (const ackBeforeRevert of defaultOptions.ackBeforeRevert) {\n\t\t\tit(`InitialOps: ${defaultOptions.initialOps} MinLen: ${minLen} ConcurrentOpsWithRevert: ${concurrentOpsWithRevert} RevertOps: ${revertOps} AckBeforeRevert: ${ackBeforeRevert}`, async () => {\n\t\t\t\tconst random = makeRandom(\n\t\t\t\t\tminLen,\n\t\t\t\t\trevertOps,\n\t\t\t\t\t[...ackBeforeRevert].reduce<number>((pv, cv) => pv + cv.charCodeAt(0), 0),\n\t\t\t\t\tconcurrentOpsWithRevert,\n\t\t\t\t);\n\n\t\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialState: \"\",\n\t\t\t\t\t\toptions: {},\n\t\t\t\t\t},\n\t\t\t\t\t\"A\",\n\t\t\t\t\t\"B\",\n\t\t\t\t\t\"C\",\n\t\t\t\t);\n\t\t\t\tlet seq = 0;\n\t\t\t\tfor (let rnd = 0; rnd < defaultOptions.rounds; rnd++) {\n\t\t\t\t\tclients.all.forEach((c) => c.updateMinSeq(seq));\n\n\t\t\t\t\tconst logger = new TestClientLogger(clients.all, `Round ${rnd}`);\n\t\t\t\t\t{\n\t\t\t\t\t\t// init with random values\n\t\t\t\t\t\tconst initialMsgs = generateOperationMessagesForClients(\n\t\t\t\t\t\t\trandom,\n\t\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\tclients.all,\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\tdefaultOptions.initialOps,\n\t\t\t\t\t\t\tminLen,\n\t\t\t\t\t\t\tdefaultOptions.operations,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tseq = applyMessages(seq, initialMsgs, clients.all, logger);\n\t\t\t\t\t}\n\n\t\t\t\t\t// cache the base text to ensure we get back to it after revert\n\t\t\t\t\tconst undoBaseText = logger.validate({\n\t\t\t\t\t\tclear: true,\n\t\t\t\t\t\terrorPrefix: \"After Initial Ops\",\n\t\t\t\t\t});\n\n\t\t\t\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\t\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\t\t\t\tconst deltaCallback = (op, delta) => {\n\t\t\t\t\t\tif (op.sequencedMessage === undefined) {\n\t\t\t\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tconst msgs: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\t\t\t\t\t{\n\t\t\t\t\t\tclientBDriver.submitOpCallback = (op) =>\n\t\t\t\t\t\t\tmsgs.push([\n\t\t\t\t\t\t\t\tclients.B.makeOpMessage(op, undefined, undefined, undefined, seq),\n\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\t\tclients.B.peekPendingSegmentGroups()!,\n\t\t\t\t\t\t\t]);\n\t\t\t\t\t\tclients.B.on(\"delta\", deltaCallback);\n\t\t\t\t\t\tmsgs.push(\n\t\t\t\t\t\t\t...generateOperationMessagesForClients(\n\t\t\t\t\t\t\t\trandom,\n\t\t\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\t\t[clients.A, clients.B],\n\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\trevertOps,\n\t\t\t\t\t\t\t\tminLen,\n\t\t\t\t\t\t\t\tdefaultOptions.operations,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (concurrentOpsWithRevert > 0) {\n\t\t\t\t\t\t// add modifications from another client\n\t\t\t\t\t\tmsgs.push(\n\t\t\t\t\t\t\t...generateOperationMessagesForClients(\n\t\t\t\t\t\t\t\trandom,\n\t\t\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\t\t[clients.A, clients.C],\n\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t\tconcurrentOpsWithRevert,\n\t\t\t\t\t\t\t\tminLen,\n\t\t\t\t\t\t\t\tdefaultOptions.operations,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet redoBaseText: string | undefined;\n\t\t\t\t\tif (ackBeforeRevert !== \"None\") {\n\t\t\t\t\t\tconst ackAll = ackBeforeRevert === \"All\";\n\t\t\t\t\t\tseq = applyMessages(\n\t\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\tmsgs.splice(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tackAll\n\t\t\t\t\t\t\t\t\t? msgs.length\n\t\t\t\t\t\t\t\t\t: random.integer(0, Math.floor(msgs.length / 2)),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tclients.all,\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (ackAll) {\n\t\t\t\t\t\t\tredoBaseText = logger.validate({ errorPrefix: \"Before Revert Ack\" });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\trevertMergeTreeDeltaRevertibles(\n\t\t\t\t\t\t\tclientBDriver,\n\t\t\t\t\t\t\tclientB_Revertibles.splice(0),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tseq = applyMessages(seq, msgs.splice(0), clients.all, logger);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthrow logger.addLogsToError(e);\n\t\t\t\t\t}\n\t\t\t\t\tlogger.validate({\n\t\t\t\t\t\tclear: true,\n\t\t\t\t\t\tbaseText: concurrentOpsWithRevert === 0 ? undoBaseText : undefined,\n\t\t\t\t\t\terrorPrefix: \"After Revert (undo)\",\n\t\t\t\t\t});\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// reset the callback before the final revert\n\t\t\t\t\t\t// to avoid accruing any new detached references\n\t\t\t\t\t\tclients.B.off(\"delta\", deltaCallback);\n\t\t\t\t\t\trevertMergeTreeDeltaRevertibles(\n\t\t\t\t\t\t\tclientBDriver,\n\t\t\t\t\t\t\tclientB_Revertibles.splice(0),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tseq = applyMessages(seq, msgs.splice(0), clients.all, logger);\n\n\t\t\t\t\t\twalkAllChildSegments(clients.B.mergeTree.root, (seg: ISegment) => {\n\t\t\t\t\t\t\tif (seg?.trackingCollection.empty === false) {\n\t\t\t\t\t\t\t\tassert.notDeepStrictEqual(\n\t\t\t\t\t\t\t\t\tseg?.trackingCollection.empty,\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\"there should be no left over tracking group\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (seg?.localRefs?.empty === false) {\n\t\t\t\t\t\t\t\tassert.notDeepStrictEqual(\n\t\t\t\t\t\t\t\t\tseg?.localRefs?.empty,\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\"there should be no left over local references\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst mergeTreeWithRevert: Partial<MergeTreeWithRevert> =\n\t\t\t\t\t\t\tclients.B.mergeTree;\n\t\t\t\t\t\tassert.notDeepStrictEqual(\n\t\t\t\t\t\t\tmergeTreeWithRevert.__mergeTreeRevertible?.detachedReferences?.localRefs\n\t\t\t\t\t\t\t\t?.empty,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\"there should be no left over local references in detached references\",\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthrow logger.addLogsToError(e);\n\t\t\t\t\t}\n\t\t\t\t\tlogger.validate({\n\t\t\t\t\t\terrorPrefix: \"After Re-Revert (redo)\",\n\t\t\t\t\t\tbaseText: redoBaseText,\n\t\t\t\t\t});\n\t\t\t\t\tlogger.dispose();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n});\n"]}
@@ -0,0 +1,17 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * Run a custom "spy function" every time the given method is invoked.
7
+ * @param methodClass - the class that has the method
8
+ * @param methodName - the name of the method
9
+ * @param spy - the spy function to run alongside the method
10
+ * @returns a function which will remove the spy function when invoked. Should be called exactly once
11
+ * after the spy is no longer needed.
12
+ *
13
+ * This method is duplicated between shared-tree test code, and should eventually
14
+ * be merged with the implementation that lives there
15
+ */
16
+ export declare function spyOnMethod(methodClass: Function, methodName: string, spy: () => void): () => void;
17
+ //# sourceMappingURL=revertibles.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revertibles.spec.d.ts","sourceRoot":"","sources":["../../src/test/revertibles.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAE1B,WAAW,EAAE,QAAQ,EACrB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,IAAI,GACb,MAAM,IAAI,CAcZ"}