@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,88 @@
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 stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
10
+ const ops_1 = require("../ops");
11
+ const localReference_1 = require("../localReference");
12
+ const mergeTreeOperationRunner_1 = require("./mergeTreeOperationRunner");
13
+ const testClient_1 = require("./testClient");
14
+ const testClientLogger_1 = require("./testClientLogger");
15
+ const testUtils_1 = require("./testUtils");
16
+ const defaultOptions = {
17
+ initLen: { min: 2, max: 256 },
18
+ modLen: { min: 1, max: 256 },
19
+ opsPerRoundRange: { min: 10, max: 10 },
20
+ rounds: 10,
21
+ operations: [mergeTreeOperationRunner_1.removeRange],
22
+ growthFunc: (input) => input * 2,
23
+ };
24
+ describe("MergeTree.Client", () => {
25
+ beforeEach(() => {
26
+ (0, localReference_1.setValidateRefCount)(testUtils_1.validateRefCount);
27
+ });
28
+ afterEach(() => {
29
+ (0, localReference_1.setValidateRefCount)(undefined);
30
+ });
31
+ // Generate a list of single character client names, support up to 69 clients
32
+ const clientNames = (0, mergeTreeOperationRunner_1.generateClientNames)();
33
+ (0, mergeTreeOperationRunner_1.doOverRanges)(defaultOptions, ({ initLen, modLen }) => {
34
+ it(`LocalReferenceFarm_${initLen}_${modLen}`, async () => {
35
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed, initLen, modLen);
36
+ const clients = new Array(3).fill(0).map(() => new testClient_1.TestClient());
37
+ clients.forEach((c, i) => c.startOrUpdateCollaboration(clientNames[i]));
38
+ let seq = 0;
39
+ // init with random values
40
+ seq = (0, mergeTreeOperationRunner_1.runMergeTreeOperationRunner)(random, seq, clients, initLen, defaultOptions);
41
+ // add local references
42
+ const refs = [];
43
+ const validateRefs = (reason, workload) => {
44
+ const preWorkload = testClientLogger_1.TestClientLogger.toString(clients);
45
+ workload();
46
+ for (let c = 1; c < clients.length; c++) {
47
+ for (let r = 0; r < refs[c].length; r++) {
48
+ const pos0 = clients[0].localReferencePositionToPosition(refs[0][r]);
49
+ const posC = clients[c].localReferencePositionToPosition(refs[c][r]);
50
+ if (pos0 !== posC) {
51
+ assert_1.strict.equal(pos0, posC, `${reason}:\n${preWorkload}\n${testClientLogger_1.TestClientLogger.toString(clients)}`);
52
+ }
53
+ }
54
+ }
55
+ // console.log(`${reason}:\n${preWorkload}\n${TestClientLogger.toString(clients)}`)
56
+ };
57
+ validateRefs("Initialize", () => {
58
+ clients.forEach((c, i) => {
59
+ refs.push([]);
60
+ for (let t = 0; t < c.getLength(); t++) {
61
+ const seg = c.getContainingSegment(t);
62
+ const forwardLref = c.createLocalReferencePosition(seg.segment, seg.offset, ops_1.ReferenceType.SlideOnRemove, { t }, localReference_1.SlidingPreference.FORWARD);
63
+ const backwardLref = c.createLocalReferencePosition(seg.segment, seg.offset, ops_1.ReferenceType.SlideOnRemove, { t }, localReference_1.SlidingPreference.BACKWARD);
64
+ refs[i].push(forwardLref);
65
+ refs[i].push(backwardLref);
66
+ }
67
+ });
68
+ });
69
+ validateRefs("After Init Zamboni", () => {
70
+ // trigger zamboni multiple times as it is incremental
71
+ for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
72
+ clients.forEach((c) => c.updateMinSeq(i));
73
+ }
74
+ });
75
+ validateRefs("After More Ops", () => {
76
+ // init with random values
77
+ seq = (0, mergeTreeOperationRunner_1.runMergeTreeOperationRunner)(random, seq, clients, modLen, defaultOptions);
78
+ });
79
+ validateRefs("After Final Zamboni", () => {
80
+ // trigger zamboni multiple times as it is incremental
81
+ for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
82
+ clients.forEach((c) => c.updateMinSeq(i));
83
+ }
84
+ });
85
+ });
86
+ });
87
+ });
88
+ //# sourceMappingURL=client.localReferenceFarm.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.localReferenceFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.localReferenceFarm.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/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"assert\";\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ReferencePosition } from \"../referencePositions\";\nimport { ReferenceType } from \"../ops\";\nimport { setValidateRefCount, SlidingPreference } from \"../localReference\";\nimport {\n\tIMergeTreeOperationRunnerConfig,\n\tremoveRange,\n\trunMergeTreeOperationRunner,\n\tgenerateClientNames,\n\tIConfigRange,\n\tdoOverRanges,\n} from \"./mergeTreeOperationRunner\";\nimport { TestClient } from \"./testClient\";\nimport { TestClientLogger } from \"./testClientLogger\";\nimport { validateRefCount } from \"./testUtils\";\n\nconst defaultOptions: Record<\"initLen\" | \"modLen\", IConfigRange> & IMergeTreeOperationRunnerConfig =\n\t{\n\t\tinitLen: { min: 2, max: 256 },\n\t\tmodLen: { min: 1, max: 256 },\n\t\topsPerRoundRange: { min: 10, max: 10 },\n\t\trounds: 10,\n\t\toperations: [removeRange],\n\t\tgrowthFunc: (input: number) => input * 2,\n\t};\n\ndescribe(\"MergeTree.Client\", () => {\n\tbeforeEach(() => {\n\t\tsetValidateRefCount(validateRefCount);\n\t});\n\n\tafterEach(() => {\n\t\tsetValidateRefCount(undefined);\n\t});\n\n\t// Generate a list of single character client names, support up to 69 clients\n\tconst clientNames = generateClientNames();\n\n\tdoOverRanges(defaultOptions, ({ initLen, modLen }) => {\n\t\tit(`LocalReferenceFarm_${initLen}_${modLen}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, initLen, modLen);\n\n\t\t\tconst clients: TestClient[] = new Array(3).fill(0).map(() => new TestClient());\n\t\t\tclients.forEach((c, i) => c.startOrUpdateCollaboration(clientNames[i]));\n\n\t\t\tlet seq = 0;\n\t\t\t// init with random values\n\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, initLen, defaultOptions);\n\t\t\t// add local references\n\t\t\tconst refs: ReferencePosition[][] = [];\n\n\t\t\tconst validateRefs = (reason: string, workload: () => void) => {\n\t\t\t\tconst preWorkload = TestClientLogger.toString(clients);\n\t\t\t\tworkload();\n\t\t\t\tfor (let c = 1; c < clients.length; c++) {\n\t\t\t\t\tfor (let r = 0; r < refs[c].length; r++) {\n\t\t\t\t\t\tconst pos0 = clients[0].localReferencePositionToPosition(refs[0][r]);\n\t\t\t\t\t\tconst posC = clients[c].localReferencePositionToPosition(refs[c][r]);\n\t\t\t\t\t\tif (pos0 !== posC) {\n\t\t\t\t\t\t\tassert.equal(\n\t\t\t\t\t\t\t\tpos0,\n\t\t\t\t\t\t\t\tposC,\n\t\t\t\t\t\t\t\t`${reason}:\\n${preWorkload}\\n${TestClientLogger.toString(clients)}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// console.log(`${reason}:\\n${preWorkload}\\n${TestClientLogger.toString(clients)}`)\n\t\t\t};\n\n\t\t\tvalidateRefs(\"Initialize\", () => {\n\t\t\t\tclients.forEach((c, i) => {\n\t\t\t\t\trefs.push([]);\n\t\t\t\t\tfor (let t = 0; t < c.getLength(); t++) {\n\t\t\t\t\t\tconst seg = c.getContainingSegment(t);\n\t\t\t\t\t\tconst forwardLref = c.createLocalReferencePosition(\n\t\t\t\t\t\t\tseg.segment!,\n\t\t\t\t\t\t\tseg.offset,\n\t\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\t\t{ t },\n\t\t\t\t\t\t\tSlidingPreference.FORWARD,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst backwardLref = c.createLocalReferencePosition(\n\t\t\t\t\t\t\tseg.segment!,\n\t\t\t\t\t\t\tseg.offset,\n\t\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\t\t{ t },\n\t\t\t\t\t\t\tSlidingPreference.BACKWARD,\n\t\t\t\t\t\t);\n\t\t\t\t\t\trefs[i].push(forwardLref);\n\t\t\t\t\t\trefs[i].push(backwardLref);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tvalidateRefs(\"After Init Zamboni\", () => {\n\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\tclients.forEach((c) => c.updateMinSeq(i));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvalidateRefs(\"After More Ops\", () => {\n\t\t\t\t// init with random values\n\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, modLen, defaultOptions);\n\t\t\t});\n\n\t\t\tvalidateRefs(\"After Final Zamboni\", () => {\n\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\tclients.forEach((c) => c.updateMinSeq(i));\n\t\t\t\t}\n\t\t\t});\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=client.rebasePosition.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.rebasePosition.spec.d.ts","sourceRoot":"","sources":["../../src/test/client.rebasePosition.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const assert_1 = require("assert");
8
+ const testClient_1 = require("./testClient");
9
+ describe("client.rebasePosition", () => {
10
+ const localUserLongId = "localUser";
11
+ const remoteUserLongId = "remoteUser";
12
+ let client;
13
+ let seq;
14
+ const getTextAt = (pos) => client.getText(pos, pos + 1);
15
+ beforeEach(() => {
16
+ client = new testClient_1.TestClient();
17
+ client.insertTextLocal(0, "hello world");
18
+ client.startOrUpdateCollaboration(localUserLongId);
19
+ seq = 0;
20
+ });
21
+ it("rebase past remote insert", () => {
22
+ client.insertTextRemote(0, "abc", undefined, ++seq, 0, remoteUserLongId);
23
+ const rebasedPos = client.rebasePosition(6 /* "w" */, 0, 0);
24
+ const text = getTextAt(rebasedPos);
25
+ assert_1.strict.equal(text, "w", "rebased pos should still refer to 'w'");
26
+ });
27
+ it("rebase past remote delete", () => {
28
+ client.removeRangeRemote(0, 3, ++seq, 0, remoteUserLongId);
29
+ const rebasedPos = client.rebasePosition(6 /* w */, 0, 0);
30
+ const text = getTextAt(rebasedPos);
31
+ assert_1.strict.equal(text, "w", "rebased pos should still refer to 'w'");
32
+ });
33
+ it("rebase on a variety of seqNumberFrom values", () => {
34
+ client.insertTextRemote(0, "abc", undefined, ++seq, 0, remoteUserLongId);
35
+ client.removeRangeRemote(0, 1, ++seq, seq - 1, remoteUserLongId);
36
+ client.insertTextRemote(1, "XYZ@", undefined, ++seq, seq - 1, remoteUserLongId);
37
+ const rebasedPos0 = client.rebasePosition(6 /* into "hello world" */, 0, 0);
38
+ const rebasedPos1 = client.rebasePosition(6 /* into "abchello world" */, 1, 0);
39
+ const rebasedPos2 = client.rebasePosition(6 /* into "bchello world" */, 2, 0);
40
+ const rebasedPos3 = client.rebasePosition(6 /* into "bXYZ@chello world" */, 3, 0);
41
+ assert_1.strict.equal(getTextAt(rebasedPos0), "w");
42
+ assert_1.strict.equal(getTextAt(rebasedPos1), "l");
43
+ assert_1.strict.equal(getTextAt(rebasedPos2), "o");
44
+ assert_1.strict.equal(getTextAt(rebasedPos3), "h");
45
+ });
46
+ describe("with subsequent local changes", () => {
47
+ // Rebasing is made more complicated from the client perspective when there are local changes applied
48
+ // meanwhile, since the local state of the string contains segments that should not be considered
49
+ // when computing the position to rebase to (since they wouldn't be visible remotely)
50
+ let op1;
51
+ let op2;
52
+ beforeEach(() => {
53
+ op1 = client.insertTextLocal(5, "123456");
54
+ op2 = client.removeRangeLocal(3, 5);
55
+ });
56
+ // For these tests, rebasedPos conceptually refers to a position that a *remote* client should use in order
57
+ // to get an equivalent position to the one that was applied locally with a different refSeq.
58
+ // Since this suite doesn't actually spin up a remote client, we verify this equivalence by asking
59
+ // the local client to resolve that remote position and confirm the text matches what's expected.
60
+ const expectTextAtRebasedPosMatches = (pos, expected, message) => {
61
+ const localViewOfRebasedPos = client.resolveRemoteClientPosition(pos, seq, remoteUserLongId);
62
+ (0, assert_1.strict)(localViewOfRebasedPos !== undefined, "pos should be defined");
63
+ const text = getTextAt(localViewOfRebasedPos);
64
+ assert_1.strict.equal(text, expected, message);
65
+ };
66
+ it("rebase past remote insert", () => {
67
+ client.insertTextRemote(0, "abc", undefined, ++seq, 0, remoteUserLongId);
68
+ const rebasedPos = client.rebasePosition(6 /* index 6 into "hello world" */, 0, 0);
69
+ const rebasedPos1 = client.rebasePosition(6 /* index 6 into "hello123456 world" */, 0, 1);
70
+ const rebasedPos2 = client.rebasePosition(6 /* index 6 into "hel123456 world" */, 0, 2);
71
+ expectTextAtRebasedPosMatches(rebasedPos, "w");
72
+ client.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);
73
+ expectTextAtRebasedPosMatches(rebasedPos1, "2");
74
+ client.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);
75
+ expectTextAtRebasedPosMatches(rebasedPos2, "4");
76
+ });
77
+ it("rebase past remote delete", () => {
78
+ client.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);
79
+ const rebasedPos = client.rebasePosition(6 /* index 6 into "hello world" */, 0, 0);
80
+ const rebasedPos1 = client.rebasePosition(6 /* index 6 into "hello123456 world" */, 0, 1);
81
+ const rebasedPos2 = client.rebasePosition(6 /* index 6 into "hel123456 world" */, 0, 2);
82
+ expectTextAtRebasedPosMatches(rebasedPos, "w");
83
+ client.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);
84
+ expectTextAtRebasedPosMatches(rebasedPos1, "2");
85
+ client.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);
86
+ expectTextAtRebasedPosMatches(rebasedPos2, "4");
87
+ });
88
+ // Mid-remote delete with meanwhile local edits isn't particularly more interesting than the cases
89
+ // handled above. Instead we include some rebased positions amid the local delete (removal of "lo")
90
+ // as this caught a bug with the original implementation.
91
+ it("rebase mid local delete", () => {
92
+ client.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);
93
+ const rebasedPos = client.rebasePosition(4 /* index 4 into "hello world" */, 0, 0);
94
+ const rebasedPos1 = client.rebasePosition(4 /* index 4 into "hello123456 world" */, 0, 1);
95
+ const rebasedPos2 = client.rebasePosition(4 /* index 4 into "hel123456 world" */, 0, 2);
96
+ assert_1.strict.equal(rebasedPos, 2);
97
+ assert_1.strict.equal(rebasedPos1, 2);
98
+ assert_1.strict.equal(rebasedPos2, 2);
99
+ });
100
+ });
101
+ });
102
+ //# sourceMappingURL=client.rebasePosition.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.rebasePosition.spec.js","sourceRoot":"","sources":["../../src/test/client.rebasePosition.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 \"assert\";\nimport { IMergeTreeOp } from \"../ops\";\nimport { TestClient } from \"./testClient\";\n\ndescribe(\"client.rebasePosition\", () => {\n\tconst localUserLongId = \"localUser\";\n\tconst remoteUserLongId = \"remoteUser\";\n\tlet client: TestClient;\n\tlet seq: number;\n\n\tconst getTextAt = (pos: number): string => client.getText(pos, pos + 1);\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tclient.insertTextLocal(0, \"hello world\");\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\t\tseq = 0;\n\t});\n\n\tit(\"rebase past remote insert\", () => {\n\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\tconst rebasedPos = client.rebasePosition(6 /* \"w\" */, 0, 0);\n\t\tconst text = getTextAt(rebasedPos);\n\t\tassert.equal(text, \"w\", \"rebased pos should still refer to 'w'\");\n\t});\n\n\tit(\"rebase past remote delete\", () => {\n\t\tclient.removeRangeRemote(0, 3, ++seq, 0, remoteUserLongId);\n\t\tconst rebasedPos = client.rebasePosition(6 /* w */, 0, 0);\n\t\tconst text = getTextAt(rebasedPos);\n\t\tassert.equal(text, \"w\", \"rebased pos should still refer to 'w'\");\n\t});\n\n\tit(\"rebase on a variety of seqNumberFrom values\", () => {\n\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\tclient.removeRangeRemote(0, 1, ++seq, seq - 1, remoteUserLongId);\n\t\tclient.insertTextRemote(1, \"XYZ@\", undefined, ++seq, seq - 1, remoteUserLongId);\n\n\t\tconst rebasedPos0 = client.rebasePosition(6 /* into \"hello world\" */, 0, 0);\n\t\tconst rebasedPos1 = client.rebasePosition(6 /* into \"abchello world\" */, 1, 0);\n\t\tconst rebasedPos2 = client.rebasePosition(6 /* into \"bchello world\" */, 2, 0);\n\t\tconst rebasedPos3 = client.rebasePosition(6 /* into \"bXYZ@chello world\" */, 3, 0);\n\n\t\tassert.equal(getTextAt(rebasedPos0), \"w\");\n\t\tassert.equal(getTextAt(rebasedPos1), \"l\");\n\t\tassert.equal(getTextAt(rebasedPos2), \"o\");\n\t\tassert.equal(getTextAt(rebasedPos3), \"h\");\n\t});\n\n\tdescribe(\"with subsequent local changes\", () => {\n\t\t// Rebasing is made more complicated from the client perspective when there are local changes applied\n\t\t// meanwhile, since the local state of the string contains segments that should not be considered\n\t\t// when computing the position to rebase to (since they wouldn't be visible remotely)\n\n\t\tlet op1: IMergeTreeOp | undefined;\n\t\tlet op2: IMergeTreeOp | undefined;\n\t\tbeforeEach(() => {\n\t\t\top1 = client.insertTextLocal(5, \"123456\");\n\t\t\top2 = client.removeRangeLocal(3, 5);\n\t\t});\n\n\t\t// For these tests, rebasedPos conceptually refers to a position that a *remote* client should use in order\n\t\t// to get an equivalent position to the one that was applied locally with a different refSeq.\n\t\t// Since this suite doesn't actually spin up a remote client, we verify this equivalence by asking\n\t\t// the local client to resolve that remote position and confirm the text matches what's expected.\n\t\tconst expectTextAtRebasedPosMatches = (pos: number, expected: string, message?: string) => {\n\t\t\tconst localViewOfRebasedPos = client.resolveRemoteClientPosition(\n\t\t\t\tpos,\n\t\t\t\tseq,\n\t\t\t\tremoteUserLongId,\n\t\t\t);\n\t\t\tassert(localViewOfRebasedPos !== undefined, \"pos should be defined\");\n\t\t\tconst text = getTextAt(localViewOfRebasedPos);\n\t\t\tassert.equal(text, expected, message);\n\t\t};\n\n\t\tit(\"rebase past remote insert\", () => {\n\t\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(6 /* index 6 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t6 /* index 6 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(6 /* index 6 into \"hel123456 world\" */, 0, 2);\n\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos, \"w\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos1, \"2\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos2, \"4\");\n\t\t});\n\n\t\tit(\"rebase past remote delete\", () => {\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(6 /* index 6 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t6 /* index 6 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(6 /* index 6 into \"hel123456 world\" */, 0, 2);\n\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos, \"w\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos1, \"2\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos2, \"4\");\n\t\t});\n\n\t\t// Mid-remote delete with meanwhile local edits isn't particularly more interesting than the cases\n\t\t// handled above. Instead we include some rebased positions amid the local delete (removal of \"lo\")\n\t\t// as this caught a bug with the original implementation.\n\t\tit(\"rebase mid local delete\", () => {\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(4 /* index 4 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t4 /* index 4 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(4 /* index 4 into \"hel123456 world\" */, 0, 2);\n\n\t\t\tassert.equal(rebasedPos, 2);\n\t\t\tassert.equal(rebasedPos1, 2);\n\t\t\tassert.equal(rebasedPos2, 2);\n\t\t});\n\t});\n});\n"]}
@@ -0,0 +1,12 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { IMergeTreeOperationRunnerConfig, IConfigRange } from "./mergeTreeOperationRunner";
6
+ interface IReconnectFarmConfig extends IMergeTreeOperationRunnerConfig {
7
+ minLength: number;
8
+ clients: IConfigRange;
9
+ }
10
+ export declare const defaultOptions: IReconnectFarmConfig;
11
+ export {};
12
+ //# sourceMappingURL=client.reconnectFarm.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.reconnectFarm.spec.d.ts","sourceRoot":"","sources":["../../src/test/client.reconnectFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAON,+BAA+B,EAC/B,YAAY,EAEZ,MAAM,4BAA4B,CAAC;AA8CpC,UAAU,oBAAqB,SAAQ,+BAA+B;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;CACtB;AAED,eAAO,MAAM,cAAc,EAAE,oBAO5B,CAAC"}
@@ -0,0 +1,91 @@
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
+ exports.defaultOptions = void 0;
9
+ const assert_1 = require("assert");
10
+ const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
11
+ const mergeTreeOperationRunner_1 = require("./mergeTreeOperationRunner");
12
+ const testClient_1 = require("./testClient");
13
+ function applyMessagesWithReconnect(startingSeq, messageDatas, clients, logger, random) {
14
+ let seq = startingSeq;
15
+ const reconnectingClientIds = clients.length > 2 && random.bool()
16
+ ? [clients[1].longClientId, clients[2].longClientId]
17
+ : [clients[1].longClientId];
18
+ const reconnectClientMsgs = new Map(reconnectingClientIds.map((id) => [id, []]));
19
+ let minSeq = 0;
20
+ // log and apply all the ops created in the round
21
+ while (messageDatas.length > 0) {
22
+ const [message, sg] = messageDatas.shift();
23
+ (0, assert_1.strict)(message.clientId, "expected clientId to be defined");
24
+ if (reconnectingClientIds.includes(message.clientId)) {
25
+ reconnectClientMsgs.get(message.clientId).push([message.contents, sg]);
26
+ }
27
+ else {
28
+ message.sequenceNumber = ++seq;
29
+ clients.forEach((c) => c.applyMsg(message));
30
+ minSeq = message.minimumSequenceNumber;
31
+ }
32
+ }
33
+ const reconnectMsgs = [];
34
+ reconnectClientMsgs.forEach((messageData, clientId) => {
35
+ const client = clients.find(({ longClientId }) => longClientId === clientId);
36
+ messageData.forEach(([op, segmentGroup]) => {
37
+ const newMsg = client.makeOpMessage(client.regeneratePendingOp(op, segmentGroup));
38
+ newMsg.minimumSequenceNumber = minSeq;
39
+ // apply message doesn't use the segment group, so just pass undefined
40
+ reconnectMsgs.push([newMsg, undefined]);
41
+ });
42
+ });
43
+ return (0, mergeTreeOperationRunner_1.applyMessages)(seq, reconnectMsgs, clients, logger);
44
+ }
45
+ exports.defaultOptions = {
46
+ minLength: 16,
47
+ clients: { min: 2, max: 8 },
48
+ opsPerRoundRange: { min: 40, max: 320 },
49
+ rounds: 3,
50
+ operations: [mergeTreeOperationRunner_1.annotateRange, mergeTreeOperationRunner_1.removeRange, mergeTreeOperationRunner_1.insert],
51
+ growthFunc: (input) => input * 2,
52
+ };
53
+ // Generate a list of single character client names, support up to 69 clients
54
+ const clientNames = (0, mergeTreeOperationRunner_1.generateClientNames)();
55
+ function runReconnectFarmTests(opts, extraSeed) {
56
+ (0, mergeTreeOperationRunner_1.doOverRange)(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {
57
+ it(`ReconnectFarm_${clientCount}_${extraSeed ?? 0}`, async () => {
58
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed, clientCount, extraSeed ?? 0);
59
+ const testOpts = { ...opts };
60
+ if (extraSeed) {
61
+ testOpts.resultsFilePostfix ?? (testOpts.resultsFilePostfix = "");
62
+ testOpts.resultsFilePostfix += extraSeed;
63
+ }
64
+ const clients = [new testClient_1.TestClient()];
65
+ clients.forEach((c, i) => c.startOrUpdateCollaboration(clientNames[i]));
66
+ let seq = 0;
67
+ clients.forEach((c) => c.updateMinSeq(seq));
68
+ // Add double the number of clients each iteration
69
+ const targetClients = Math.max(opts.clients.min, clientCount);
70
+ for (let cc = clients.length; cc < targetClients; cc++) {
71
+ const newClient = await testClient_1.TestClient.createFromClientSnapshot(clients[0], clientNames[cc]);
72
+ clients.push(newClient);
73
+ }
74
+ seq = (0, mergeTreeOperationRunner_1.runMergeTreeOperationRunner)(random, seq, clients, testOpts.minLength, testOpts, applyMessagesWithReconnect);
75
+ }).timeout(30 * 1000);
76
+ });
77
+ }
78
+ (0, stochastic_test_utils_1.describeFuzz)("MergeTree.Client", ({ testCount }) => {
79
+ const opts = exports.defaultOptions;
80
+ if (testCount > 1) {
81
+ (0, mergeTreeOperationRunner_1.doOverRange)({ min: 0, max: testCount - 1 }, (x) => x + 1, (seed) => {
82
+ describe(`with seed ${seed}`, () => {
83
+ runReconnectFarmTests(opts, seed);
84
+ });
85
+ });
86
+ }
87
+ else {
88
+ runReconnectFarmTests(opts);
89
+ }
90
+ });
91
+ //# sourceMappingURL=client.reconnectFarm.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.reconnectFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.reconnectFarm.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/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"assert\";\nimport { IRandom, makeRandom, describeFuzz } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { IMergeTreeOp } from \"../ops\";\nimport { SegmentGroup } from \"../mergeTreeNodes\";\nimport {\n\tgenerateClientNames,\n\tdoOverRange,\n\trunMergeTreeOperationRunner,\n\tannotateRange,\n\tremoveRange,\n\tapplyMessages,\n\tIMergeTreeOperationRunnerConfig,\n\tIConfigRange,\n\tinsert,\n} from \"./mergeTreeOperationRunner\";\nimport { TestClient } from \"./testClient\";\nimport { TestClientLogger } from \"./testClientLogger\";\n\nfunction applyMessagesWithReconnect(\n\tstartingSeq: number,\n\tmessageDatas: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\trandom: IRandom,\n) {\n\tlet seq = startingSeq;\n\tconst reconnectingClientIds =\n\t\tclients.length > 2 && random.bool()\n\t\t\t? [clients[1].longClientId!, clients[2].longClientId!]\n\t\t\t: [clients[1].longClientId!];\n\tconst reconnectClientMsgs: Map<string, [IMergeTreeOp, SegmentGroup | SegmentGroup[]][]> =\n\t\tnew Map(reconnectingClientIds.map((id) => [id, []]));\n\tlet minSeq = 0;\n\t// log and apply all the ops created in the round\n\twhile (messageDatas.length > 0) {\n\t\tconst [message, sg] = messageDatas.shift()!;\n\t\tassert(message.clientId, \"expected clientId to be defined\");\n\t\tif (reconnectingClientIds.includes(message.clientId)) {\n\t\t\treconnectClientMsgs.get(message.clientId)!.push([message.contents as IMergeTreeOp, sg]);\n\t\t} else {\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tclients.forEach((c) => c.applyMsg(message));\n\t\t\tminSeq = message.minimumSequenceNumber;\n\t\t}\n\t}\n\n\tconst reconnectMsgs: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\treconnectClientMsgs.forEach((messageData, clientId) => {\n\t\tconst client = clients.find(({ longClientId }) => longClientId === clientId)!;\n\t\tmessageData.forEach(([op, segmentGroup]) => {\n\t\t\tconst newMsg = client.makeOpMessage(client.regeneratePendingOp(op, segmentGroup));\n\t\t\tnewMsg.minimumSequenceNumber = minSeq;\n\t\t\t// apply message doesn't use the segment group, so just pass undefined\n\t\t\treconnectMsgs.push([newMsg, undefined as any]);\n\t\t});\n\t});\n\n\treturn applyMessages(seq, reconnectMsgs, clients, logger);\n}\n\ninterface IReconnectFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: number;\n\tclients: IConfigRange;\n}\n\nexport const defaultOptions: IReconnectFarmConfig = {\n\tminLength: 16,\n\tclients: { min: 2, max: 8 },\n\topsPerRoundRange: { min: 40, max: 320 },\n\trounds: 3,\n\toperations: [annotateRange, removeRange, insert],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\n// Generate a list of single character client names, support up to 69 clients\nconst clientNames = generateClientNames();\n\nfunction runReconnectFarmTests(opts: IReconnectFarmConfig, extraSeed?: number): void {\n\tdoOverRange(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {\n\t\tit(`ReconnectFarm_${clientCount}_${extraSeed ?? 0}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, clientCount, extraSeed ?? 0);\n\t\t\tconst testOpts = { ...opts };\n\t\t\tif (extraSeed) {\n\t\t\t\ttestOpts.resultsFilePostfix ??= \"\";\n\t\t\t\ttestOpts.resultsFilePostfix += extraSeed;\n\t\t\t}\n\n\t\t\tconst clients: TestClient[] = [new TestClient()];\n\t\t\tclients.forEach((c, i) => c.startOrUpdateCollaboration(clientNames[i]));\n\n\t\t\tlet seq = 0;\n\t\t\tclients.forEach((c) => c.updateMinSeq(seq));\n\n\t\t\t// Add double the number of clients each iteration\n\t\t\tconst targetClients = Math.max(opts.clients.min, clientCount);\n\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\tclients[0],\n\t\t\t\t\tclientNames[cc],\n\t\t\t\t);\n\t\t\t\tclients.push(newClient);\n\t\t\t}\n\n\t\t\tseq = runMergeTreeOperationRunner(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\ttestOpts.minLength,\n\t\t\t\ttestOpts,\n\t\t\t\tapplyMessagesWithReconnect,\n\t\t\t);\n\t\t}).timeout(30 * 1000);\n\t});\n}\n\ndescribeFuzz(\"MergeTree.Client\", ({ testCount }) => {\n\tconst opts = defaultOptions;\n\n\tif (testCount > 1) {\n\t\tdoOverRange(\n\t\t\t{ min: 0, max: testCount - 1 },\n\t\t\t(x) => x + 1,\n\t\t\t(seed) => {\n\t\t\t\tdescribe(`with seed ${seed}`, () => {\n\t\t\t\t\trunReconnectFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunReconnectFarmTests(opts);\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=client.replay.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.replay.spec.d.ts","sourceRoot":"","sources":["../../src/test/client.replay.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,85 @@
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
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || function (mod) {
24
+ if (mod && mod.__esModule) return mod;
25
+ var result = {};
26
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27
+ __setModuleDefault(result, mod);
28
+ return result;
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ const fs = __importStar(require("fs"));
35
+ const assert_1 = __importDefault(require("assert"));
36
+ const ops_1 = require("../ops");
37
+ const opBuilder_1 = require("../opBuilder");
38
+ const testClient_1 = require("./testClient");
39
+ const mergeTreeOperationRunner_1 = require("./mergeTreeOperationRunner");
40
+ const testClientLogger_1 = require("./testClientLogger");
41
+ describe("MergeTree.Client", () => {
42
+ for (const filePath of fs.readdirSync(mergeTreeOperationRunner_1.replayResultsPath)) {
43
+ it(`Replay ${filePath}`, async () => {
44
+ const file = JSON.parse(fs.readFileSync(`${mergeTreeOperationRunner_1.replayResultsPath}/${filePath}`).toString());
45
+ const msgClients = new Map();
46
+ const originalClient = new testClient_1.TestClient();
47
+ msgClients.set("A", { client: originalClient, msgs: [] });
48
+ originalClient.insertTextLocal(0, file[0].initialText);
49
+ originalClient.startOrUpdateCollaboration("A");
50
+ for (const group of file) {
51
+ for (const msg of group.msgs) {
52
+ (0, assert_1.default)(msg.clientId, "expected clientId to be defined");
53
+ if (!msgClients.has(msg.clientId)) {
54
+ const client = await testClient_1.TestClient.createFromClientSnapshot(originalClient, msg.clientId);
55
+ msgClients.set(msg.clientId, { client, msgs: [] });
56
+ }
57
+ }
58
+ }
59
+ for (const group of file) {
60
+ const logger = new testClientLogger_1.TestClientLogger([...msgClients.values()].map((mc) => mc.client));
61
+ const initialText = logger.validate();
62
+ assert_1.default.strictEqual(initialText, group.initialText, "Initial text not as expected");
63
+ for (const msg of group.msgs) {
64
+ const msgClient = msgClients.get(msg.clientId);
65
+ while (msgClient.msgs.length > 0 &&
66
+ msg.referenceSequenceNumber > msgClient.client.getCurrentSeq()) {
67
+ msgClient.client.applyMsg(msgClient.msgs.shift());
68
+ }
69
+ const op = msg.contents;
70
+ msgClient.client.localTransaction(op.type === ops_1.MergeTreeDeltaType.GROUP ? op : (0, opBuilder_1.createGroupOp)(op));
71
+ msgClients.forEach((mc) => mc.msgs.push(msg));
72
+ }
73
+ msgClients.forEach((mc) => {
74
+ while (mc.msgs.length > 0) {
75
+ mc.client.applyMsg(mc.msgs.shift());
76
+ }
77
+ });
78
+ const result = logger.validate();
79
+ assert_1.default.strictEqual(result, group.resultText, "Result text not as expected");
80
+ logger.dispose();
81
+ }
82
+ }).timeout(30 * 10000);
83
+ }
84
+ });
85
+ //# sourceMappingURL=client.replay.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.replay.spec.js","sourceRoot":"","sources":["../../src/test/client.replay.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;AACH,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE7D,uCAAyB;AACzB,oDAA4B;AAE5B,gCAA0D;AAC1D,4CAA6C;AAC7C,6CAA0C;AAC1C,yEAA4E;AAC5E,yDAAsD;AAEtD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IACjC,KAAK,MAAM,QAAQ,IAAI,EAAE,CAAC,WAAW,CAAC,4CAAiB,CAAC,EAAE;QACzD,EAAE,CAAC,UAAU,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE;YACnC,MAAM,IAAI,GAAkB,IAAI,CAAC,KAAK,CACrC,EAAE,CAAC,YAAY,CAAC,GAAG,4CAAiB,IAAI,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAC9D,CAAC;YACF,MAAM,UAAU,GAAG,IAAI,GAAG,EAGvB,CAAC;YACJ,MAAM,cAAc,GAAG,IAAI,uBAAU,EAAE,CAAC;YACxC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1D,cAAc,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACvD,cAAc,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YAC/C,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE;gBACzB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE;oBAC7B,IAAA,gBAAM,EAAC,GAAG,CAAC,QAAQ,EAAE,iCAAiC,CAAC,CAAC;oBACxD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;wBAClC,MAAM,MAAM,GAAG,MAAM,uBAAU,CAAC,wBAAwB,CACvD,cAAc,EACd,GAAG,CAAC,QAAQ,CACZ,CAAC;wBACF,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;qBACnD;iBACD;aACD;YACD,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE;gBACzB,MAAM,MAAM,GAAG,IAAI,mCAAgB,CAClC,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAC/C,CAAC;gBACF,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,gBAAM,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,8BAA8B,CAAC,CAAC;gBACnF,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE;oBAC7B,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,QAAS,CAAE,CAAC;oBACjD,OACC,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;wBACzB,GAAG,CAAC,uBAAuB,GAAG,SAAS,CAAC,MAAM,CAAC,aAAa,EAAE,EAC7D;wBACD,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAG,CAAC,CAAC;qBACnD;oBACD,MAAM,EAAE,GAAG,GAAG,CAAC,QAAwB,CAAC;oBACxC,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAChC,EAAE,CAAC,IAAI,KAAK,wBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,yBAAa,EAAC,EAAE,CAAC,CAC7D,CAAC;oBACF,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;iBAC9C;gBAED,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;oBACzB,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;wBAC1B,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAG,CAAC,CAAC;qBACrC;gBACF,CAAC,CAAC,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACjC,gBAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,6BAA6B,CAAC,CAAC;gBAC5E,MAAM,CAAC,OAAO,EAAE,CAAC;aACjB;QACF,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;KACvB;AACF,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 * as fs from \"fs\";\nimport assert from \"assert\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops\";\nimport { createGroupOp } from \"../opBuilder\";\nimport { TestClient } from \"./testClient\";\nimport { ReplayGroup, replayResultsPath } from \"./mergeTreeOperationRunner\";\nimport { TestClientLogger } from \"./testClientLogger\";\n\ndescribe(\"MergeTree.Client\", () => {\n\tfor (const filePath of fs.readdirSync(replayResultsPath)) {\n\t\tit(`Replay ${filePath}`, async () => {\n\t\t\tconst file: ReplayGroup[] = JSON.parse(\n\t\t\t\tfs.readFileSync(`${replayResultsPath}/${filePath}`).toString(),\n\t\t\t);\n\t\t\tconst msgClients = new Map<\n\t\t\t\tstring,\n\t\t\t\t{ client: TestClient; msgs: ISequencedDocumentMessage[] }\n\t\t\t>();\n\t\t\tconst originalClient = new TestClient();\n\t\t\tmsgClients.set(\"A\", { client: originalClient, msgs: [] });\n\t\t\toriginalClient.insertTextLocal(0, file[0].initialText);\n\t\t\toriginalClient.startOrUpdateCollaboration(\"A\");\n\t\t\tfor (const group of file) {\n\t\t\t\tfor (const msg of group.msgs) {\n\t\t\t\t\tassert(msg.clientId, \"expected clientId to be defined\");\n\t\t\t\t\tif (!msgClients.has(msg.clientId)) {\n\t\t\t\t\t\tconst client = await TestClient.createFromClientSnapshot(\n\t\t\t\t\t\t\toriginalClient,\n\t\t\t\t\t\t\tmsg.clientId,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmsgClients.set(msg.clientId, { client, msgs: [] });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const group of file) {\n\t\t\t\tconst logger = new TestClientLogger(\n\t\t\t\t\t[...msgClients.values()].map((mc) => mc.client),\n\t\t\t\t);\n\t\t\t\tconst initialText = logger.validate();\n\t\t\t\tassert.strictEqual(initialText, group.initialText, \"Initial text not as expected\");\n\t\t\t\tfor (const msg of group.msgs) {\n\t\t\t\t\tconst msgClient = msgClients.get(msg.clientId!)!;\n\t\t\t\t\twhile (\n\t\t\t\t\t\tmsgClient.msgs.length > 0 &&\n\t\t\t\t\t\tmsg.referenceSequenceNumber > msgClient.client.getCurrentSeq()\n\t\t\t\t\t) {\n\t\t\t\t\t\tmsgClient.client.applyMsg(msgClient.msgs.shift()!);\n\t\t\t\t\t}\n\t\t\t\t\tconst op = msg.contents as IMergeTreeOp;\n\t\t\t\t\tmsgClient.client.localTransaction(\n\t\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op : createGroupOp(op),\n\t\t\t\t\t);\n\t\t\t\t\tmsgClients.forEach((mc) => mc.msgs.push(msg));\n\t\t\t\t}\n\n\t\t\t\tmsgClients.forEach((mc) => {\n\t\t\t\t\twhile (mc.msgs.length > 0) {\n\t\t\t\t\t\tmc.client.applyMsg(mc.msgs.shift()!);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tconst result = logger.validate();\n\t\t\t\tassert.strictEqual(result, group.resultText, \"Result text not as expected\");\n\t\t\t\tlogger.dispose();\n\t\t\t}\n\t\t}).timeout(30 * 10000);\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=client.rollback.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.rollback.spec.d.ts","sourceRoot":"","sources":["../../src/test/client.rollback.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}