@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,1333 @@
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
+ exports.DocumentTree = exports.RandomPack = exports.TestPack = exports.mergeTreeCheckedTest = exports.mergeTreeLargeTest = exports.mergeTreeTest1 = exports.makeTextSegment = exports.fileTest1 = exports.integerTest1 = exports.simpleTest = void 0;
11
+ /* eslint-disable @typescript-eslint/consistent-type-assertions, no-bitwise */
12
+ /* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
13
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
14
+ /* eslint-disable @typescript-eslint/no-base-to-string */
15
+ const assert_1 = require("assert");
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const path_1 = __importDefault(require("path"));
18
+ const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
19
+ const client_utils_1 = require("@fluid-internal/client-utils");
20
+ const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
21
+ const diff_1 = __importDefault(require("diff"));
22
+ const collections_1 = require("../collections");
23
+ const constants_1 = require("../constants");
24
+ const mergeTreeNodes_1 = require("../mergeTreeNodes");
25
+ const opBuilder_1 = require("../opBuilder");
26
+ const ops_1 = require("../ops");
27
+ const snapshotlegacy_1 = require("../snapshotlegacy");
28
+ const textSegment_1 = require("../textSegment");
29
+ const referencePositions_1 = require("../referencePositions");
30
+ const mergeTree_1 = require("../mergeTree");
31
+ const MergeTreeTextHelper_1 = require("../MergeTreeTextHelper");
32
+ const testClient_1 = require("./testClient");
33
+ const testServer_1 = require("./testServer");
34
+ const testUtils_1 = require("./testUtils");
35
+ function LinearDictionary(compareKeys) {
36
+ const props = [];
37
+ const compareProps = (a, b) => compareKeys(a.key, b.key);
38
+ function mapRange(action, accum, start, end) {
39
+ let _start = start;
40
+ let _end = end;
41
+ if (props.length !== 0) {
42
+ return;
43
+ }
44
+ if (_start === undefined) {
45
+ _start = min().key;
46
+ }
47
+ if (_end === undefined) {
48
+ _end = max().key;
49
+ }
50
+ for (let i = 0, len = props.length; i < len; i++) {
51
+ if (compareKeys(_start, props[i].key) <= 0) {
52
+ const ecmp = compareKeys(_end, props[i].key);
53
+ if (ecmp < 0) {
54
+ break;
55
+ }
56
+ if (!action(props[i], accum)) {
57
+ break;
58
+ }
59
+ }
60
+ }
61
+ }
62
+ function map(action, accum) {
63
+ mapRange(action, accum);
64
+ }
65
+ function min() {
66
+ if (props.length > 0) {
67
+ return props[0];
68
+ }
69
+ }
70
+ function max() {
71
+ if (props.length > 0) {
72
+ return props[props.length - 1];
73
+ }
74
+ }
75
+ function get(key) {
76
+ for (let i = 0, len = props.length; i < len; i++) {
77
+ if (props[i].key === key) {
78
+ return props[i];
79
+ }
80
+ }
81
+ }
82
+ function put(key, data) {
83
+ if (key !== undefined) {
84
+ if (data === undefined) {
85
+ remove(key);
86
+ }
87
+ else {
88
+ props.push({ key, data });
89
+ props.sort(compareProps); // Go to insertion sort if too slow
90
+ }
91
+ }
92
+ }
93
+ function remove(key) {
94
+ if (key !== undefined) {
95
+ for (let i = 0, len = props.length; i < len; i++) {
96
+ if (props[i].key === key) {
97
+ props[i] = props[len - 1];
98
+ props.length--;
99
+ props.sort(compareProps);
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ return {
106
+ min,
107
+ max,
108
+ map,
109
+ mapRange,
110
+ remove,
111
+ get,
112
+ put,
113
+ };
114
+ }
115
+ let logLines;
116
+ function log(message) {
117
+ if (logLines) {
118
+ logLines.push(message.toString());
119
+ }
120
+ }
121
+ function printStringProperty(p) {
122
+ log(`[${p?.key}, ${p?.data}]`);
123
+ return true;
124
+ }
125
+ function printStringNumProperty(p) {
126
+ log(`[${p.key}, ${p.data}]`);
127
+ return true;
128
+ }
129
+ function simpleTest() {
130
+ const a = ["Aardvark", "cute", "Baboon", "big", "Chameleon", "colorful", "Dingo", "wild"];
131
+ const beast = new collections_1.RedBlackTree(mergeTreeNodes_1.compareStrings);
132
+ for (let i = 0; i < a.length; i += 2) {
133
+ beast.put(a[i], a[i + 1]);
134
+ }
135
+ beast.map(printStringProperty);
136
+ log("Map B D");
137
+ log("Map Aardvark Dingo");
138
+ log("Map Baboon Chameleon");
139
+ printStringProperty(beast.get("Chameleon"));
140
+ }
141
+ exports.simpleTest = simpleTest;
142
+ const clock = () => client_utils_1.Trace.start();
143
+ function took(desc, trace) {
144
+ const duration = trace.trace().duration;
145
+ log(`${desc} took ${duration} ms`);
146
+ return duration;
147
+ }
148
+ function elapsedMicroseconds(trace) {
149
+ return trace.trace().duration * 1000;
150
+ }
151
+ function integerTest1() {
152
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed);
153
+ const imin = 0;
154
+ const imax = 10000000;
155
+ const intCount = 1100000;
156
+ const beast = new collections_1.RedBlackTree(mergeTreeNodes_1.compareNumbers);
157
+ const randInt = () => random.integer(imin, imax);
158
+ const pos = new Array(intCount);
159
+ let i = 0;
160
+ let redo = false;
161
+ function onConflict(key, currentKey) {
162
+ redo = true;
163
+ return { data: currentKey };
164
+ }
165
+ let conflictCount = 0;
166
+ let start = clock();
167
+ while (i < intCount) {
168
+ pos[i] = randInt();
169
+ beast.put(pos[i], i, onConflict);
170
+ if (!redo) {
171
+ i++;
172
+ }
173
+ else {
174
+ conflictCount++;
175
+ redo = false;
176
+ }
177
+ }
178
+ took("test gen", start);
179
+ const errorCount = 0;
180
+ start = clock();
181
+ for (let j = 0, len = pos.length; j < len; j++) {
182
+ const cp = pos[j];
183
+ /* let prop = */ beast.get(cp);
184
+ }
185
+ const getdur = took("get all keys", start);
186
+ log(`cost per get is ${((1000.0 * getdur) / intCount).toFixed(3)} us`);
187
+ log(`duplicates ${conflictCount}, errors ${errorCount}`);
188
+ return errorCount;
189
+ }
190
+ exports.integerTest1 = integerTest1;
191
+ function fileTest1() {
192
+ const content = fs_1.default.readFileSync(path_1.default.join(__dirname, "../../../public/literature/shakespeare.txt"), "utf8");
193
+ const a = content.split("\n");
194
+ const iterCount = a.length >> 2;
195
+ const removeCount = 10;
196
+ log(`len: ${a.length}`);
197
+ for (let k = 0; k < iterCount; k++) {
198
+ const beast = new collections_1.RedBlackTree(mergeTreeNodes_1.compareStrings);
199
+ const linearBeast = LinearDictionary(mergeTreeNodes_1.compareStrings);
200
+ for (let i = 0, len = a.length; i < len; i++) {
201
+ a[i] = a[i].trim();
202
+ if (a[i].length > 0) {
203
+ beast.put(a[i], i);
204
+ linearBeast.put(a[i], i);
205
+ }
206
+ }
207
+ if (k === 0) {
208
+ beast.map(printStringNumProperty);
209
+ log("BTREE...");
210
+ }
211
+ const removedAnimals = [];
212
+ for (let j = 0; j < removeCount; j++) {
213
+ const removeIndex = Math.floor(Math.random() * a.length);
214
+ log(`Removing: ${a[removeIndex]} at ${removeIndex}`);
215
+ beast.remove(a[removeIndex]);
216
+ linearBeast.remove(a[removeIndex]);
217
+ removedAnimals.push(a[removeIndex]);
218
+ }
219
+ for (const animal of a) {
220
+ if (animal.length > 0 && !removedAnimals.includes(animal)) {
221
+ const prop = beast.get(animal);
222
+ const linProp = linearBeast.get(animal);
223
+ // log(`Trying key ${animal}`);
224
+ if (prop) {
225
+ // printStringNumProperty(prop);
226
+ if (linProp === undefined ||
227
+ prop.key !== linProp.key ||
228
+ prop.data !== linProp.data) {
229
+ log(`Linear BST does not match RB BST at key ${animal}`);
230
+ }
231
+ }
232
+ else {
233
+ log(`hmm...bad key: ${animal}`);
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }
239
+ exports.fileTest1 = fileTest1;
240
+ function printTextSegment(textSegment, pos) {
241
+ log(textSegment.toString());
242
+ log(`at [${pos}, ${pos + textSegment.cachedLength})`);
243
+ return true;
244
+ }
245
+ function makeTextSegment(text) {
246
+ return new textSegment_1.TextSegment(text);
247
+ }
248
+ exports.makeTextSegment = makeTextSegment;
249
+ function makeCollabTextSegment(text) {
250
+ return new textSegment_1.TextSegment(text);
251
+ }
252
+ function editFlat(source, s, dl, nt = "") {
253
+ return source.substring(0, s) + nt + source.substring(s + dl, source.length);
254
+ }
255
+ let accumTime = 0;
256
+ function checkInsertMergeTree(mergeTree, pos, textSegment, verbose = false) {
257
+ let checkText = new MergeTreeTextHelper_1.MergeTreeTextHelper(mergeTree).getText(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
258
+ checkText = editFlat(checkText, pos, 0, textSegment.text);
259
+ const clockStart = clock();
260
+ (0, testUtils_1.insertText)({
261
+ mergeTree,
262
+ pos,
263
+ refSeq: constants_1.UniversalSequenceNumber,
264
+ clientId: constants_1.LocalClientId,
265
+ seq: constants_1.UniversalSequenceNumber,
266
+ text: textSegment.text,
267
+ props: undefined,
268
+ opArgs: undefined,
269
+ });
270
+ accumTime += elapsedMicroseconds(clockStart);
271
+ const updatedText = new MergeTreeTextHelper_1.MergeTreeTextHelper(mergeTree).getText(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
272
+ const result = checkText === updatedText;
273
+ if (!result && verbose) {
274
+ log(`mismatch(o): ${checkText}`);
275
+ log(`mismatch(u): ${updatedText}`);
276
+ }
277
+ return result;
278
+ }
279
+ function checkMarkRemoveMergeTree(mergeTree, start, end, verbose = false) {
280
+ const helper = new MergeTreeTextHelper_1.MergeTreeTextHelper(mergeTree);
281
+ const origText = helper.getText(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
282
+ const checkText = editFlat(origText, start, end - start);
283
+ const clockStart = clock();
284
+ mergeTree.markRangeRemoved(start, end, constants_1.UniversalSequenceNumber, constants_1.LocalClientId, constants_1.UniversalSequenceNumber, false, { op: (0, opBuilder_1.createRemoveRangeOp)(start, end) });
285
+ accumTime += elapsedMicroseconds(clockStart);
286
+ const updatedText = helper.getText(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
287
+ const result = checkText === updatedText;
288
+ if (!result && verbose) {
289
+ log(`mismatch(o): ${origText}`);
290
+ log(`mismatch(c): ${checkText}`);
291
+ log(`mismatch(u): ${updatedText}`);
292
+ }
293
+ return result;
294
+ }
295
+ function mergeTreeTest1() {
296
+ const mergeTree = new mergeTree_1.MergeTree();
297
+ mergeTree.insertSegments(0, [textSegment_1.TextSegment.make("the cat is on the mat")], constants_1.UniversalSequenceNumber, constants_1.LocalClientId, constants_1.UniversalSequenceNumber, undefined);
298
+ mergeTree.mapRange(printTextSegment, constants_1.UniversalSequenceNumber, constants_1.LocalClientId, undefined);
299
+ let fuzzySeg = makeCollabTextSegment("fuzzy, fuzzy ");
300
+ checkInsertMergeTree(mergeTree, 4, fuzzySeg);
301
+ fuzzySeg = makeCollabTextSegment("fuzzy, fuzzy ");
302
+ checkInsertMergeTree(mergeTree, 4, fuzzySeg);
303
+ checkMarkRemoveMergeTree(mergeTree, 4, 13);
304
+ // checkRemoveSegTree(segTree, 4, 13);
305
+ checkInsertMergeTree(mergeTree, 4, makeCollabTextSegment("fi"));
306
+ mergeTree.mapRange(printTextSegment, constants_1.UniversalSequenceNumber, constants_1.LocalClientId, undefined);
307
+ const segoff = mergeTree.getContainingSegment(4, constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
308
+ log(mergeTree.getPosition(segoff.segment, constants_1.UniversalSequenceNumber, constants_1.LocalClientId));
309
+ log(new MergeTreeTextHelper_1.MergeTreeTextHelper(mergeTree).getText(constants_1.UniversalSequenceNumber, constants_1.LocalClientId));
310
+ log(mergeTree.toString());
311
+ TestPack().firstTest();
312
+ }
313
+ exports.mergeTreeTest1 = mergeTreeTest1;
314
+ function mergeTreeLargeTest() {
315
+ const mergeTree = new mergeTree_1.MergeTree();
316
+ mergeTree.insertSegments(0, [textSegment_1.TextSegment.make("the cat is on the mat")], constants_1.UniversalSequenceNumber, constants_1.LocalClientId, constants_1.UniversalSequenceNumber, undefined);
317
+ const insertCount = 1000000;
318
+ const removeCount = 980000;
319
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed);
320
+ const imin = 1;
321
+ const imax = 9;
322
+ const randInt = () => random.integer(imin, imax);
323
+ function randomString(len, c) {
324
+ let str = "";
325
+ for (let i = 0; i < len; i++) {
326
+ str += c;
327
+ }
328
+ return str;
329
+ }
330
+ accumTime = 0;
331
+ let accumTreeSize = 0;
332
+ let treeCount = 0;
333
+ for (let i = 0; i < insertCount; i++) {
334
+ const slen = randInt();
335
+ const s = randomString(slen, String.fromCharCode(48 + slen));
336
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
337
+ const pos = random.integer(0, preLen);
338
+ const clockStart = clock();
339
+ (0, testUtils_1.insertText)({
340
+ mergeTree,
341
+ pos,
342
+ refSeq: constants_1.UniversalSequenceNumber,
343
+ clientId: constants_1.LocalClientId,
344
+ seq: constants_1.UniversalSequenceNumber,
345
+ text: s,
346
+ props: undefined,
347
+ opArgs: undefined,
348
+ });
349
+ accumTime += elapsedMicroseconds(clockStart);
350
+ if (i > 0 && 0 === i % 50000) {
351
+ const perIter = (accumTime / (i + 1)).toFixed(3);
352
+ treeCount++;
353
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
354
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
355
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per insert with average tree size ${averageTreeSize}`);
356
+ }
357
+ }
358
+ log(process.memoryUsage().heapUsed);
359
+ accumTime = 0;
360
+ accumTreeSize = 0;
361
+ treeCount = 0;
362
+ for (let i = 0; i < removeCount; i++) {
363
+ const dlen = randInt();
364
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
365
+ const pos = random.integer(0, preLen);
366
+ // Log(itree.toString());
367
+ const clockStart = clock();
368
+ mergeTree.markRangeRemoved(pos, pos + dlen, constants_1.UniversalSequenceNumber, constants_1.LocalClientId, constants_1.UniversalSequenceNumber, false, undefined);
369
+ accumTime += elapsedMicroseconds(clockStart);
370
+ if (i > 0 && 0 === i % 50000) {
371
+ const perIter = (accumTime / (i + 1)).toFixed(3);
372
+ treeCount++;
373
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
374
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
375
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per del with average tree size ${averageTreeSize}`);
376
+ }
377
+ }
378
+ }
379
+ exports.mergeTreeLargeTest = mergeTreeLargeTest;
380
+ function mergeTreeCheckedTest() {
381
+ const mergeTree = new mergeTree_1.MergeTree();
382
+ mergeTree.insertSegments(0, [textSegment_1.TextSegment.make("the cat is on the mat")], constants_1.UniversalSequenceNumber, constants_1.LocalClientId, constants_1.UniversalSequenceNumber, undefined);
383
+ const insertCount = 2000;
384
+ const removeCount = 1400;
385
+ const largeRemoveCount = 20;
386
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed);
387
+ const imin = 1;
388
+ const imax = 9;
389
+ const randInt = () => random.integer(imin, imax);
390
+ const randLargeInt = () => random.integer(10, 1000);
391
+ function randomString(len, c) {
392
+ let str = "";
393
+ for (let i = 0; i < len; i++) {
394
+ str += c;
395
+ }
396
+ return str;
397
+ }
398
+ accumTime = 0;
399
+ let accumTreeSize = 0;
400
+ let treeCount = 0;
401
+ let errorCount = 0;
402
+ for (let i = 0; i < insertCount; i++) {
403
+ const slen = randInt();
404
+ const s = randomString(slen, String.fromCharCode(48 + slen));
405
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
406
+ const pos = random.integer(0, preLen);
407
+ if (!checkInsertMergeTree(mergeTree, pos, makeCollabTextSegment(s), true)) {
408
+ log(`i: ${i} preLen ${preLen} pos: ${pos} slen: ${slen} s: ${s} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
409
+ log(mergeTree.toString());
410
+ errorCount++;
411
+ break;
412
+ }
413
+ if (i > 0 && 0 === i % 1000) {
414
+ const perIter = (accumTime / (i + 1)).toFixed(3);
415
+ treeCount++;
416
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
417
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
418
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per insert with average tree size ${averageTreeSize}`);
419
+ }
420
+ }
421
+ accumTime = 0;
422
+ accumTreeSize = 0;
423
+ treeCount = 0;
424
+ for (let i = 0; i < largeRemoveCount; i++) {
425
+ const dlen = randLargeInt();
426
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
427
+ const pos = random.integer(0, preLen);
428
+ // log(itree.toString());
429
+ if (!checkMarkRemoveMergeTree(mergeTree, pos, pos + dlen, true)) {
430
+ log(`i: ${i} preLen ${preLen} pos: ${pos} dlen: ${dlen} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
431
+ log(mergeTree.toString());
432
+ break;
433
+ }
434
+ if (i > 0 && 0 === i % 10) {
435
+ const perIter = (accumTime / (i + 1)).toFixed(3);
436
+ treeCount++;
437
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
438
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
439
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per large del with average tree size ${averageTreeSize}`);
440
+ }
441
+ }
442
+ accumTime = 0;
443
+ accumTreeSize = 0;
444
+ treeCount = 0;
445
+ for (let i = 0; i < removeCount; i++) {
446
+ const dlen = randInt();
447
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
448
+ const pos = random.integer(0, preLen);
449
+ // log(itree.toString());
450
+ if (i & 1) {
451
+ if (!checkMarkRemoveMergeTree(mergeTree, pos, pos + dlen, true)) {
452
+ log(`mr i: ${i} preLen ${preLen} pos: ${pos} dlen: ${dlen} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
453
+ log(mergeTree.toString());
454
+ errorCount++;
455
+ break;
456
+ }
457
+ }
458
+ else {
459
+ if (!checkMarkRemoveMergeTree(mergeTree, pos, pos + dlen, true)) {
460
+ log(`i: ${i} preLen ${preLen} pos: ${pos} dlen: ${dlen} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
461
+ log(mergeTree.toString());
462
+ errorCount++;
463
+ break;
464
+ }
465
+ }
466
+ if (i > 0 && 0 === i % 1000) {
467
+ const perIter = (accumTime / (i + 1)).toFixed(3);
468
+ treeCount++;
469
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
470
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
471
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per del with average tree size ${averageTreeSize}`);
472
+ }
473
+ }
474
+ accumTime = 0;
475
+ accumTreeSize = 0;
476
+ treeCount = 0;
477
+ for (let i = 0; i < insertCount; i++) {
478
+ const slen = randInt();
479
+ const s = randomString(slen, String.fromCharCode(48 + slen));
480
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
481
+ const pos = random.integer(0, preLen);
482
+ if (!checkInsertMergeTree(mergeTree, pos, makeCollabTextSegment(s), true)) {
483
+ log(`i: ${i} preLen ${preLen} pos: ${pos} slen: ${slen} s: ${s} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
484
+ log(mergeTree.toString());
485
+ errorCount++;
486
+ break;
487
+ }
488
+ if (i > 0 && 0 === i % 1000) {
489
+ const perIter = (accumTime / (i + 1)).toFixed(3);
490
+ treeCount++;
491
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
492
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
493
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per insert with average tree size ${averageTreeSize}`);
494
+ }
495
+ }
496
+ accumTime = 0;
497
+ accumTreeSize = 0;
498
+ treeCount = 0;
499
+ for (let i = 0; i < removeCount; i++) {
500
+ const dlen = randInt();
501
+ const preLen = mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
502
+ const pos = random.integer(0, preLen);
503
+ // log(itree.toString());
504
+ if (i & 1) {
505
+ if (!checkMarkRemoveMergeTree(mergeTree, pos, pos + dlen, true)) {
506
+ log(`i: ${i} preLen ${preLen} pos: ${pos} dlen: ${dlen} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
507
+ log(mergeTree.toString());
508
+ errorCount++;
509
+ break;
510
+ }
511
+ }
512
+ else {
513
+ if (!checkMarkRemoveMergeTree(mergeTree, pos, pos + dlen, true)) {
514
+ log(`i: ${i} preLen ${preLen} pos: ${pos} dlen: ${dlen} itree len: ${mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId)}`);
515
+ log(mergeTree.toString());
516
+ errorCount++;
517
+ break;
518
+ }
519
+ }
520
+ if (i > 0 && 0 === i % 1000) {
521
+ const perIter = (accumTime / (i + 1)).toFixed(3);
522
+ treeCount++;
523
+ accumTreeSize += mergeTree.getLength(constants_1.UniversalSequenceNumber, constants_1.LocalClientId);
524
+ const averageTreeSize = (accumTreeSize / treeCount).toFixed(3);
525
+ log(`i: ${i} time: ${accumTime}us which is average ${perIter} per del with average tree size ${averageTreeSize}`);
526
+ }
527
+ }
528
+ return errorCount;
529
+ }
530
+ exports.mergeTreeCheckedTest = mergeTreeCheckedTest;
531
+ function TestPack(verbose = true) {
532
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed);
533
+ const minSegCount = 1;
534
+ const maxSegCount = 1000;
535
+ const randSmallSegmentCount = () => random.integer(1, 4);
536
+ const randSegmentCount = () => random.integer(minSegCount, maxSegCount);
537
+ const randTextLength = () => random.integer(1, 5);
538
+ const zedCode = 48;
539
+ function randomString(len, c) {
540
+ let str = "";
541
+ for (let i = 0; i < len; i++) {
542
+ str += c;
543
+ }
544
+ return str;
545
+ }
546
+ let getTextTime = 0;
547
+ let getTextCalls = 0;
548
+ const catchUpTime = 0;
549
+ const catchUps = 0;
550
+ function reportTiming(client) {
551
+ if (!verbose) {
552
+ return;
553
+ }
554
+ const aveTime = (client.accumTime / client.accumOps).toFixed(1);
555
+ const stats = (0, testClient_1.getStats)(client.mergeTree);
556
+ const windowTime = stats.windowTime;
557
+ const packTime = stats.packTime;
558
+ const aveWindowTime = ((windowTime || 0) / client.accumOps).toFixed(1);
559
+ const avePackTime = ((packTime ?? 0) / client.accumOps).toFixed(1);
560
+ const aveExtraWindowTime = (client.accumWindowTime / client.accumOps).toFixed(1);
561
+ const aveWindow = (client.accumWindow / client.accumOps).toFixed(1);
562
+ const adjTime = ((client.accumTime - (windowTime - client.accumWindowTime)) /
563
+ client.accumOps).toFixed(1);
564
+ const aveGetTextTime = (getTextTime / getTextCalls).toFixed(1);
565
+ let aveCatchUpTime = "off";
566
+ if (catchUps > 0) {
567
+ aveCatchUpTime = (catchUpTime / catchUps).toFixed(1);
568
+ }
569
+ log(`get text time: ${aveGetTextTime} catch up ${aveCatchUpTime}`);
570
+ log(`accum time ${client.accumTime} us ops: ${client.accumOps} ave time ${aveTime} - wtime ${adjTime} pack ${avePackTime} ave window ${aveWindow}`);
571
+ log(`accum window time ${client.accumWindowTime} us ave window time total ${aveWindowTime} not in ops ${aveExtraWindowTime}; max ${client.maxWindowTime}`);
572
+ }
573
+ function manyMergeTrees() {
574
+ const mergeTreeCount = 2000000;
575
+ const a = Array(mergeTreeCount);
576
+ for (let i = 0; i < mergeTreeCount; i++) {
577
+ a[i] = new mergeTree_1.MergeTree();
578
+ }
579
+ for (;;) { }
580
+ }
581
+ function clientServer(startFile, initRounds = 1000) {
582
+ const clientCount = 5;
583
+ const fileSegCount = 0;
584
+ let initString = "";
585
+ if (!startFile) {
586
+ initString = "don't ask for whom the bell tolls; it tolls for thee";
587
+ }
588
+ const server = new testServer_1.TestServer();
589
+ server.insertTextLocal(0, initString);
590
+ server.measureOps = true;
591
+ if (startFile) {
592
+ (0, testUtils_1.loadTextFromFile)(startFile, server.mergeTree, fileSegCount);
593
+ }
594
+ const clients = new Array(clientCount);
595
+ for (let i = 0; i < clientCount; i++) {
596
+ clients[i] = new testClient_1.TestClient();
597
+ clients[i].insertTextLocal(0, initString);
598
+ clients[i].measureOps = true;
599
+ if (startFile) {
600
+ (0, testUtils_1.loadTextFromFile)(startFile, clients[i].mergeTree, fileSegCount);
601
+ }
602
+ clients[i].startOrUpdateCollaboration(`Fred${i}`);
603
+ }
604
+ server.startOrUpdateCollaboration("theServer");
605
+ server.addClients(clients);
606
+ function checkTextMatch() {
607
+ // log(`checking text match @${server.getCurrentSeq()}`);
608
+ const clockStart = clock();
609
+ const serverText = server.getText();
610
+ getTextTime += elapsedMicroseconds(clockStart);
611
+ getTextCalls++;
612
+ for (const client of clients) {
613
+ const cliText = client.getText();
614
+ if (cliText !== serverText) {
615
+ log(`mismatch @${server.getCurrentSeq()} client @${client.getCurrentSeq()} id: ${client.getClientId()}`);
616
+ // log(serverText);
617
+ // log(cliText);
618
+ const diffParts = diff_1.default.diffChars(serverText, cliText);
619
+ for (const diffPart of diffParts) {
620
+ let annotes = "";
621
+ if (diffPart.added) {
622
+ annotes += "added ";
623
+ }
624
+ else if (diffPart.removed) {
625
+ annotes += "removed ";
626
+ }
627
+ if (diffPart.count) {
628
+ annotes += `count: ${diffPart.count}`;
629
+ }
630
+ log(`text: ${diffPart.value} ${annotes}`);
631
+ }
632
+ log(server.mergeTree.toString());
633
+ log(client.mergeTree.toString());
634
+ return true;
635
+ }
636
+ }
637
+ return false;
638
+ }
639
+ const rounds = initRounds;
640
+ function clientProcessSome(client, all = false) {
641
+ const cliMsgCount = client.getMessageCount();
642
+ const countToApply = all
643
+ ? cliMsgCount
644
+ : random.integer(Math.floor((2 * cliMsgCount) / 3), cliMsgCount);
645
+ client.applyMessages(countToApply);
646
+ }
647
+ function serverProcessSome(_server, all = false) {
648
+ const svrMsgCount = _server.getMessageCount();
649
+ const countToApply = all
650
+ ? svrMsgCount
651
+ : random.integer(Math.floor((2 * svrMsgCount) / 3), svrMsgCount);
652
+ return _server.applyMessages(countToApply);
653
+ }
654
+ function randomSpateOfInserts(client, charIndex) {
655
+ const textLen = randTextLength();
656
+ const text = randomString(textLen, String.fromCharCode(zedCode + ((client.getCurrentSeq() + charIndex) % 50)));
657
+ const preLen = client.getLength();
658
+ const pos = random.integer(0, preLen);
659
+ const insertTextOp = client.insertTextLocal(pos, text);
660
+ server.enqueueMsg(client.makeOpMessage(insertTextOp, constants_1.UnassignedSequenceNumber));
661
+ if (testClient_1.TestClient.useCheckQ) {
662
+ client.enqueueTestString();
663
+ }
664
+ }
665
+ function randomSpateOfRemoves(client) {
666
+ const dlen = randTextLength();
667
+ const preLen = client.getLength();
668
+ const pos = random.integer(0, preLen);
669
+ const op = client.removeRangeLocal(pos, pos + dlen);
670
+ server.enqueueMsg(client.makeOpMessage(op));
671
+ if (testClient_1.TestClient.useCheckQ) {
672
+ client.enqueueTestString();
673
+ }
674
+ }
675
+ function randomWordMove(client) {
676
+ const word1 = client.findRandomWord();
677
+ if (word1) {
678
+ const removeStart = word1.pos;
679
+ const removeEnd = removeStart + word1.text.length;
680
+ const removeOp = client.removeRangeLocal(removeStart, removeEnd);
681
+ server.enqueueMsg(client.makeOpMessage(removeOp, constants_1.UnassignedSequenceNumber));
682
+ if (testClient_1.TestClient.useCheckQ) {
683
+ client.enqueueTestString();
684
+ }
685
+ let word2 = client.findRandomWord();
686
+ while (!word2) {
687
+ word2 = client.findRandomWord();
688
+ }
689
+ const pos = word2.pos + word2.text.length;
690
+ const insertOp = client.insertTextLocal(pos, word1.text);
691
+ server.enqueueMsg(client.makeOpMessage(insertOp, constants_1.UnassignedSequenceNumber));
692
+ if (testClient_1.TestClient.useCheckQ) {
693
+ client.enqueueTestString();
694
+ }
695
+ }
696
+ }
697
+ let errorCount = 0;
698
+ const extractSnapTime = 0;
699
+ const extractSnapOps = 0;
700
+ function finishRound(roundCount) {
701
+ // Process remaining messages
702
+ if (serverProcessSome(server, true)) {
703
+ return;
704
+ }
705
+ for (const client of clients) {
706
+ clientProcessSome(client, true);
707
+ }
708
+ if (0 === roundCount % 100) {
709
+ const clockStart = clock();
710
+ if (checkTextMatch()) {
711
+ log(`round: ${roundCount} BREAK`);
712
+ errorCount++;
713
+ return errorCount;
714
+ }
715
+ checkTime += elapsedMicroseconds(clockStart);
716
+ if (verbose) {
717
+ log(`wall clock is ${((Date.now() - startTime) / 1000.0).toFixed(1)}`);
718
+ }
719
+ const stats = (0, testClient_1.getStats)(server.mergeTree);
720
+ const liveAve = (stats.liveCount / stats.nodeCount).toFixed(1);
721
+ const posLeaves = stats.leafCount - stats.removedLeafCount;
722
+ let aveExtractSnapTime = "off";
723
+ if (extractSnapOps > 0) {
724
+ aveExtractSnapTime = (extractSnapTime / extractSnapOps).toFixed(1);
725
+ }
726
+ log(`round: ${roundCount} seq ${server.seq} char count ${server.getLength()} height ${stats.maxHeight} lv ${stats.leafCount} rml ${stats.removedLeafCount} p ${posLeaves} nodes ${stats.nodeCount} pop ${liveAve} histo ${stats.histo}`);
727
+ if (extractSnapOps > 0) {
728
+ aveExtractSnapTime = (extractSnapTime / extractSnapOps).toFixed(1);
729
+ log(`ave extract snap time ${aveExtractSnapTime}`);
730
+ }
731
+ reportTiming(server);
732
+ reportTiming(clients[2]);
733
+ let totalTime = server.accumTime + server.accumWindowTime;
734
+ for (const client of clients) {
735
+ totalTime += client.accumTime + client.accumWindowTime;
736
+ }
737
+ if (verbose) {
738
+ log(`total time ${(totalTime / 1000000.0).toFixed(1)} check time ${(checkTime / 1000000.0).toFixed(1)}`);
739
+ }
740
+ // log(server.getText());
741
+ // log(server.mergeTree.toString());
742
+ }
743
+ return errorCount;
744
+ }
745
+ function round(roundCount) {
746
+ for (const client of clients) {
747
+ const insertSegmentCount = randSmallSegmentCount();
748
+ for (let j = 0; j < insertSegmentCount; j++) {
749
+ if (startFile) {
750
+ randomWordMove(client);
751
+ }
752
+ else {
753
+ randomSpateOfInserts(client, j);
754
+ }
755
+ }
756
+ if (serverProcessSome(server)) {
757
+ return;
758
+ }
759
+ clientProcessSome(client);
760
+ let removeSegmentCount = Math.floor((3 * insertSegmentCount) / 4);
761
+ if (removeSegmentCount < 1) {
762
+ removeSegmentCount = 1;
763
+ }
764
+ for (let j = 0; j < removeSegmentCount; j++) {
765
+ if (startFile) {
766
+ randomWordMove(client);
767
+ }
768
+ else {
769
+ randomSpateOfRemoves(client);
770
+ }
771
+ }
772
+ if (serverProcessSome(server)) {
773
+ return;
774
+ }
775
+ clientProcessSome(client);
776
+ }
777
+ finishRound(roundCount);
778
+ }
779
+ const startTime = Date.now();
780
+ let checkTime = 0;
781
+ for (let i = 0; i < rounds; i++) {
782
+ round(i);
783
+ if (errorCount > 0) {
784
+ break;
785
+ }
786
+ }
787
+ tail();
788
+ function tail() {
789
+ reportTiming(server);
790
+ reportTiming(clients[2]);
791
+ // log(server.getText());
792
+ // log(server.mergeTree.toString());
793
+ }
794
+ return errorCount;
795
+ }
796
+ function randolicious() {
797
+ const insertRounds = 40;
798
+ const removeRounds = 32;
799
+ const cliA = new testClient_1.TestClient();
800
+ cliA.insertTextLocal(0, "a stitch in time saves nine");
801
+ cliA.startOrUpdateCollaboration("FredA");
802
+ const cliB = new testClient_1.TestClient();
803
+ cliB.insertTextLocal(0, "a stitch in time saves nine");
804
+ cliB.startOrUpdateCollaboration("FredB");
805
+ function checkTextMatch(checkSeq) {
806
+ let error = false;
807
+ if (cliA.getCurrentSeq() !== checkSeq) {
808
+ log(`client A has seq number ${cliA.getCurrentSeq()} mismatch with ${checkSeq}`);
809
+ error = true;
810
+ }
811
+ if (cliB.getCurrentSeq() !== checkSeq) {
812
+ log(`client B has seq number ${cliB.getCurrentSeq()} mismatch with ${checkSeq}`);
813
+ error = true;
814
+ }
815
+ const aText = cliA.getText();
816
+ const bText = cliB.getText();
817
+ if (aText !== bText) {
818
+ log(`mismatch @${checkSeq}:`);
819
+ log(aText);
820
+ log(bText);
821
+ error = true;
822
+ }
823
+ if (!(0, testUtils_1.nodeOrdinalsHaveIntegrity)(cliA.mergeTree.root)) {
824
+ error = true;
825
+ }
826
+ if (!(0, testUtils_1.nodeOrdinalsHaveIntegrity)(cliB.mergeTree.root)) {
827
+ error = true;
828
+ }
829
+ return error;
830
+ }
831
+ let min = 0;
832
+ cliA.accumTime = 0;
833
+ cliB.accumTime = 0;
834
+ function insertTest() {
835
+ for (let i = 0; i < insertRounds; i++) {
836
+ let insertCount = randSegmentCount();
837
+ let sequenceNumber = cliA.getCurrentSeq() + 1;
838
+ let firstSeq = sequenceNumber;
839
+ const cliAMsgs = [];
840
+ for (let j = 0; j < insertCount; j++) {
841
+ const textLen = randTextLength();
842
+ const text = randomString(textLen, String.fromCharCode(zedCode + (sequenceNumber % 50)));
843
+ const preLen = cliA.getLength();
844
+ const pos = random.integer(0, preLen);
845
+ const msg = cliA.makeOpMessage(cliA.insertTextLocal(pos, text), sequenceNumber++);
846
+ msg.minimumSequenceNumber = min;
847
+ cliAMsgs.push(msg);
848
+ cliB.applyMsg(msg);
849
+ }
850
+ for (let k = firstSeq; k < sequenceNumber; k++) {
851
+ cliA.applyMsg(cliAMsgs.shift());
852
+ }
853
+ if (checkTextMatch(sequenceNumber - 1)) {
854
+ return true;
855
+ }
856
+ min = sequenceNumber - 1;
857
+ insertCount = randSegmentCount();
858
+ sequenceNumber = cliA.getCurrentSeq() + 1;
859
+ firstSeq = sequenceNumber;
860
+ const cliBMsgs = [];
861
+ for (let j = 0; j < insertCount; j++) {
862
+ const textLen = randTextLength();
863
+ const text = randomString(textLen, String.fromCharCode(zedCode + (sequenceNumber % 50)));
864
+ const preLen = cliB.getLength();
865
+ const pos = random.integer(0, preLen);
866
+ const msg = cliB.makeOpMessage(cliB.insertTextLocal(pos, text), sequenceNumber++);
867
+ msg.minimumSequenceNumber = min;
868
+ cliBMsgs.push(msg);
869
+ cliA.applyMsg(msg);
870
+ }
871
+ for (let k = firstSeq; k < sequenceNumber; k++) {
872
+ cliB.applyMsg(cliBMsgs.shift());
873
+ }
874
+ if (checkTextMatch(sequenceNumber - 1)) {
875
+ return true;
876
+ }
877
+ min = sequenceNumber - 1;
878
+ }
879
+ return false;
880
+ }
881
+ function removeTest() {
882
+ for (let i = 0; i < removeRounds; i++) {
883
+ let removeCount = randSegmentCount();
884
+ let sequenceNumber = cliA.getCurrentSeq() + 1;
885
+ let firstSeq = sequenceNumber;
886
+ const cliAMsgs = [];
887
+ for (let j = 0; j < removeCount; j++) {
888
+ const dlen = randTextLength();
889
+ const maxStartPos = cliA.getLength() - dlen;
890
+ const pos = random.integer(0, maxStartPos);
891
+ const msg = cliA.makeOpMessage(cliA.removeRangeLocal(pos, pos + dlen), sequenceNumber++);
892
+ msg.minimumSequenceNumber = min;
893
+ cliAMsgs.push(msg);
894
+ cliB.applyMsg(msg);
895
+ }
896
+ for (let k = firstSeq; k < sequenceNumber; k++) {
897
+ cliA.applyMsg(cliAMsgs.shift());
898
+ }
899
+ if (checkTextMatch(sequenceNumber - 1)) {
900
+ return true;
901
+ }
902
+ min = sequenceNumber - 1;
903
+ removeCount = randSegmentCount();
904
+ sequenceNumber = cliA.getCurrentSeq() + 1;
905
+ firstSeq = sequenceNumber;
906
+ const cliBMsgs = [];
907
+ for (let j = 0; j < removeCount; j++) {
908
+ const dlen = randTextLength();
909
+ const maxStartPos = cliB.getLength() - dlen;
910
+ const pos = random.integer(0, maxStartPos);
911
+ const msg = cliB.makeOpMessage(cliB.removeRangeLocal(pos, pos + dlen), sequenceNumber++);
912
+ msg.minimumSequenceNumber = min;
913
+ cliBMsgs.push(msg);
914
+ cliA.applyMsg(msg);
915
+ }
916
+ for (let k = firstSeq; k < sequenceNumber; k++) {
917
+ cliB.applyMsg(cliBMsgs.shift());
918
+ }
919
+ if (checkTextMatch(sequenceNumber - 1)) {
920
+ return true;
921
+ }
922
+ min = sequenceNumber - 1;
923
+ }
924
+ return false;
925
+ }
926
+ let errorCount = 0;
927
+ if (insertTest()) {
928
+ log(cliA.mergeTree.toString());
929
+ log(cliB.mergeTree.toString());
930
+ errorCount++;
931
+ }
932
+ else {
933
+ log(`sequence number: ${cliA.getCurrentSeq()} min: ${cliA.getCollabWindow().minSeq}`);
934
+ // log(cliA.mergeTree.toString());
935
+ log(`testing remove at ${cliA.getCurrentSeq()} and ${cliB.getCurrentSeq()}`);
936
+ if (removeTest()) {
937
+ log(cliA.mergeTree.toString());
938
+ log(cliB.mergeTree.toString());
939
+ errorCount++;
940
+ }
941
+ }
942
+ log(`sequence number: ${cliA.getCurrentSeq()} min: ${cliA.getCollabWindow().minSeq}`);
943
+ // log(cliA.mergeTree.toString());
944
+ // log(cliB.mergeTree.toString());
945
+ // log(cliA.getText());
946
+ const aveWindow = ((minSegCount + maxSegCount) / 2).toFixed(1);
947
+ const aveTime = (cliA.accumTime / cliA.accumOps).toFixed(3);
948
+ const aveWindowTime = (cliA.accumWindowTime / cliA.accumOps).toFixed(3);
949
+ if (verbose) {
950
+ log(`accum time ${cliA.accumTime} us ops: ${cliA.accumOps} ave window ${aveWindow} ave time ${aveTime}`);
951
+ log(`accum window time ${cliA.accumWindowTime} us ave window time ${aveWindowTime}; max ${cliA.maxWindowTime}`);
952
+ }
953
+ // log(cliB.getText());
954
+ return errorCount;
955
+ }
956
+ const clientNames = ["Ed", "Ted", "Ned", "Harv", "Marv", "Glenda", "Susan"];
957
+ function firstTest() {
958
+ let cli = new testClient_1.TestClient();
959
+ cli.insertTextLocal(0, "on the mat.");
960
+ cli.startOrUpdateCollaboration("Fred1");
961
+ for (const cname of clientNames) {
962
+ cli.addLongClientId(cname);
963
+ }
964
+ cli.insertTextRemote(0, "that ", undefined, 1, 0, "1");
965
+ if (verbose) {
966
+ log(cli.mergeTree.toString());
967
+ }
968
+ cli.insertTextRemote(0, "fat ", undefined, 2, 0, "2");
969
+ if (verbose) {
970
+ log(cli.mergeTree.toString());
971
+ }
972
+ cli.insertTextLocal(5, "cat ");
973
+ if (verbose) {
974
+ log(cli.mergeTree.toString());
975
+ }
976
+ if (verbose) {
977
+ for (let i = 0; i < 4; i++) {
978
+ for (let j = 0; j < 3; j++) {
979
+ log(cli.relText(i, j));
980
+ }
981
+ }
982
+ }
983
+ cli.mergeTree.ackPendingSegment(createLocalOpArgs(ops_1.MergeTreeDeltaType.INSERT, 3));
984
+ if (verbose) {
985
+ log(cli.mergeTree.toString());
986
+ for (let clientId = 0; clientId < 4; clientId++) {
987
+ for (let refSeq = 0; refSeq < 4; refSeq++) {
988
+ log(cli.relText(clientId, refSeq));
989
+ }
990
+ }
991
+ }
992
+ cli.insertMarkerRemote(0, { refType: ops_1.ReferenceType.Tile }, { [referencePositions_1.reservedTileLabelsKey]: ["peach"] }, 5, 0, "2");
993
+ cli.insertTextRemote(6, "very ", undefined, 6, 2, "2");
994
+ if (verbose) {
995
+ log(cli.mergeTree.toString());
996
+ for (let clientId = 0; clientId < 4; clientId++) {
997
+ for (let refSeq = 0; refSeq < 7; refSeq++) {
998
+ log(cli.relText(clientId, refSeq));
999
+ }
1000
+ }
1001
+ }
1002
+ const segs = (new snapshotlegacy_1.SnapshotLegacy(cli.mergeTree, (0, telemetry_utils_1.createChildLogger)({ namespace: "fluid:snapshot" }))
1003
+ .extractSync()
1004
+ .map((seg) => seg.toJSONObject()));
1005
+ if (verbose) {
1006
+ for (const seg of segs) {
1007
+ log(`${(0, testClient_1.specToSegment)(seg)}`);
1008
+ }
1009
+ }
1010
+ cli = new testClient_1.TestClient();
1011
+ cli.insertTextLocal(0, " old sock!");
1012
+ cli.startOrUpdateCollaboration("Fred2");
1013
+ for (const cname of clientNames) {
1014
+ cli.addLongClientId(cname);
1015
+ }
1016
+ cli.insertTextRemote(0, "abcde", undefined, 1, 0, "2");
1017
+ cli.insertTextRemote(0, "yyy", undefined, 2, 0, "1");
1018
+ cli.insertTextRemote(2, "zzz", undefined, 3, 1, "3");
1019
+ cli.insertTextRemote(1, "EAGLE", undefined, 4, 1, "4");
1020
+ cli.insertTextRemote(4, "HAS", undefined, 5, 1, "5");
1021
+ cli.insertTextLocal(19, " LANDED");
1022
+ cli.insertTextRemote(0, "yowza: ", undefined, 6, 4, "2");
1023
+ cli.mergeTree.ackPendingSegment(createLocalOpArgs(ops_1.MergeTreeDeltaType.INSERT, 7));
1024
+ if (verbose) {
1025
+ log(cli.mergeTree.toString());
1026
+ for (let clientId = 0; clientId < 6; clientId++) {
1027
+ for (let refSeq = 0; refSeq < 8; refSeq++) {
1028
+ log(cli.relText(clientId, refSeq));
1029
+ }
1030
+ }
1031
+ }
1032
+ cli.applyMsg(cli.makeOpMessage((0, opBuilder_1.createRemoveRangeOp)(3, 5), 8, 6, "1"));
1033
+ if (verbose) {
1034
+ log(cli.mergeTree.toString());
1035
+ for (let clientId = 0; clientId < 6; clientId++) {
1036
+ for (let refSeq = 0; refSeq < 9; refSeq++) {
1037
+ log(cli.relText(clientId, refSeq));
1038
+ }
1039
+ }
1040
+ }
1041
+ cli = new testClient_1.TestClient();
1042
+ cli.insertTextLocal(0, "abcdefgh");
1043
+ cli.startOrUpdateCollaboration("Fred3");
1044
+ for (const cname of clientNames) {
1045
+ cli.addLongClientId(cname);
1046
+ }
1047
+ cli.applyMsg(cli.makeOpMessage((0, opBuilder_1.createRemoveRangeOp)(1, 3), 1, 0, "3"));
1048
+ if (verbose) {
1049
+ log(cli.mergeTree.toString());
1050
+ }
1051
+ cli.insertTextRemote(2, "zzz", undefined, 2, 0, "2");
1052
+ if (verbose) {
1053
+ log(cli.mergeTree.toString());
1054
+ }
1055
+ cli.insertTextRemote(9, " chaser", undefined, 3, 2, "3");
1056
+ cli.removeRangeLocal(12, 14);
1057
+ cli.mergeTree.ackPendingSegment(createLocalOpArgs(ops_1.MergeTreeDeltaType.REMOVE, 4));
1058
+ if (verbose) {
1059
+ log(cli.mergeTree.toString());
1060
+ for (let clientId = 0; clientId < 4; clientId++) {
1061
+ for (let refSeq = 0; refSeq < 5; refSeq++) {
1062
+ log(cli.relText(clientId, refSeq));
1063
+ }
1064
+ }
1065
+ }
1066
+ cli.insertTextLocal(14, "*yolumba*");
1067
+ cli.insertTextLocal(17, "-zanzibar-");
1068
+ cli.mergeTree.ackPendingSegment(createLocalOpArgs(ops_1.MergeTreeDeltaType.INSERT, 5));
1069
+ cli.insertTextRemote(2, "(aaa)", undefined, 6, 4, "2");
1070
+ cli.mergeTree.ackPendingSegment(createLocalOpArgs(ops_1.MergeTreeDeltaType.INSERT, 7));
1071
+ if (verbose) {
1072
+ log(cli.mergeTree.toString());
1073
+ for (let clientId = 0; clientId < 4; clientId++) {
1074
+ for (let refSeq = 0; refSeq < 8; refSeq++) {
1075
+ log(cli.relText(clientId, refSeq));
1076
+ }
1077
+ }
1078
+ }
1079
+ /*
1080
+ cli.removeRangeLocal(3,8);
1081
+ cli.removeRangeLocal(5,7);
1082
+ cli.ackPendingSegment(8);
1083
+ cli.ackPendingSegment(9);
1084
+ */
1085
+ cli.applyMsg(cli.makeOpMessage((0, opBuilder_1.createRemoveRangeOp)(3, 8), 8, 7, "2"));
1086
+ cli.applyMsg(cli.makeOpMessage((0, opBuilder_1.createRemoveRangeOp)(5, 7), 9, 7, "2"));
1087
+ if (verbose) {
1088
+ log(cli.mergeTree.toString());
1089
+ for (let clientId = 0; clientId < 4; clientId++) {
1090
+ for (let refSeq = 0; refSeq < 10; refSeq++) {
1091
+ log(cli.relText(clientId, refSeq));
1092
+ }
1093
+ }
1094
+ }
1095
+ const removeOp = cli.removeRangeLocal(3, 5);
1096
+ cli.applyMsg(cli.makeOpMessage((0, opBuilder_1.createRemoveRangeOp)(3, 6), 10, 9, "2"));
1097
+ cli.applyMsg(cli.makeOpMessage(removeOp, 11));
1098
+ if (verbose) {
1099
+ log(cli.mergeTree.toString());
1100
+ for (let clientId = 0; clientId < 4; clientId++) {
1101
+ for (let refSeq = 0; refSeq < 12; refSeq++) {
1102
+ log(cli.relText(clientId, refSeq));
1103
+ }
1104
+ }
1105
+ }
1106
+ }
1107
+ return {
1108
+ firstTest,
1109
+ randolicious,
1110
+ clientServer,
1111
+ manyMergeTrees,
1112
+ };
1113
+ }
1114
+ exports.TestPack = TestPack;
1115
+ const createLocalOpArgs = (type, sequenceNumber) => ({
1116
+ op: { type },
1117
+ sequencedMessage: {
1118
+ sequenceNumber,
1119
+ },
1120
+ });
1121
+ class RandomPack {
1122
+ constructor() {
1123
+ this.random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed);
1124
+ }
1125
+ randInteger(min, max) {
1126
+ return this.random.integer(min, max);
1127
+ }
1128
+ randString(wordCount) {
1129
+ const exampleWords = [
1130
+ "giraffe",
1131
+ "hut",
1132
+ "aardvark",
1133
+ "gold",
1134
+ "hover",
1135
+ "yurt",
1136
+ "hot",
1137
+ "antelope",
1138
+ "gift",
1139
+ "banana",
1140
+ "book",
1141
+ "airplane",
1142
+ "kitten",
1143
+ "moniker",
1144
+ "lemma",
1145
+ "doughnut",
1146
+ "orange",
1147
+ "tangerine",
1148
+ ];
1149
+ let buf = "";
1150
+ for (let i = 0; i < wordCount; i++) {
1151
+ const exampleWord = exampleWords[this.randInteger(0, exampleWords.length - 1)];
1152
+ if (i > 0) {
1153
+ buf += " ";
1154
+ }
1155
+ buf += exampleWord;
1156
+ }
1157
+ return buf;
1158
+ }
1159
+ }
1160
+ exports.RandomPack = RandomPack;
1161
+ /**
1162
+ * Generate and model documents from the following tree grammar:
1163
+ * Row -\> row[Box*];
1164
+ * Box -\> box[Content];
1165
+ * Content -\> (Row|Paragraph)*;
1166
+ * Paragraph -\> pgtile text;
1167
+ * Document -\> Content
1168
+ */
1169
+ class DocumentTree {
1170
+ constructor(name, children) {
1171
+ this.name = name;
1172
+ this.children = children;
1173
+ this.pos = 0;
1174
+ this.ids = { box: 0, row: 0 };
1175
+ }
1176
+ addToMergeTree(client, docNode) {
1177
+ if (typeof docNode === "string") {
1178
+ const text = docNode;
1179
+ client.insertTextLocal(this.pos, text);
1180
+ this.pos += text.length;
1181
+ }
1182
+ else {
1183
+ let id;
1184
+ if (docNode.name === "pg") {
1185
+ client.insertMarkerLocal(this.pos, ops_1.ReferenceType.Tile, {
1186
+ [referencePositions_1.reservedTileLabelsKey]: [docNode.name],
1187
+ });
1188
+ this.pos++;
1189
+ }
1190
+ else {
1191
+ const trid = docNode.name + this.ids[docNode.name].toString();
1192
+ docNode.id = trid;
1193
+ id = this.ids[docNode.name]++;
1194
+ const props = {
1195
+ [mergeTreeNodes_1.reservedMarkerIdKey]: trid,
1196
+ [referencePositions_1.reservedRangeLabelsKey]: [docNode.name],
1197
+ };
1198
+ let behaviors = ops_1.ReferenceType.Simple;
1199
+ if (docNode.name === "row") {
1200
+ props[referencePositions_1.reservedTileLabelsKey] = ["pg"];
1201
+ behaviors |= ops_1.ReferenceType.Tile;
1202
+ }
1203
+ client.insertMarkerLocal(this.pos, behaviors, props);
1204
+ this.pos++;
1205
+ }
1206
+ for (const child of docNode.children) {
1207
+ this.addToMergeTree(client, child);
1208
+ }
1209
+ if (docNode.name !== "pg") {
1210
+ const etrid = `end-${docNode.name}${id?.toString()}`;
1211
+ client.insertMarkerLocal(this.pos, ops_1.ReferenceType.Simple, {
1212
+ [mergeTreeNodes_1.reservedMarkerIdKey]: etrid,
1213
+ [referencePositions_1.reservedRangeLabelsKey]: [docNode.name],
1214
+ });
1215
+ this.pos++;
1216
+ }
1217
+ }
1218
+ }
1219
+ static generateDocument() {
1220
+ const tree = new DocumentTree("Document", DocumentTree.generateContent(0.6));
1221
+ return tree;
1222
+ }
1223
+ static generateContent(rowProbability) {
1224
+ let _rowProbability = rowProbability;
1225
+ const items = [];
1226
+ const docLen = DocumentTree.randPack.randInteger(7, 25);
1227
+ for (let i = 0; i < docLen; i++) {
1228
+ const rowThreshold = _rowProbability * 1000;
1229
+ const selector = DocumentTree.randPack.randInteger(1, 1000);
1230
+ if (selector >= rowThreshold) {
1231
+ const pg = DocumentTree.generateParagraph();
1232
+ items.push(pg);
1233
+ }
1234
+ else {
1235
+ _rowProbability /= 2;
1236
+ if (_rowProbability < 0.08) {
1237
+ _rowProbability = 0;
1238
+ }
1239
+ const row = DocumentTree.generateRow(_rowProbability);
1240
+ items.push(row);
1241
+ }
1242
+ }
1243
+ return items;
1244
+ }
1245
+ // Model pg tile as tree with single child
1246
+ static generateParagraph() {
1247
+ const wordCount = DocumentTree.randPack.randInteger(1, 6);
1248
+ const text = DocumentTree.randPack.randString(wordCount);
1249
+ const pgTree = new DocumentTree("pg", [text]);
1250
+ return pgTree;
1251
+ }
1252
+ static generateRow(rowProbability) {
1253
+ const items = [];
1254
+ const rowLen = DocumentTree.randPack.randInteger(1, 5);
1255
+ for (let i = 0; i < rowLen; i++) {
1256
+ const item = DocumentTree.generateBox(rowProbability);
1257
+ items.push(item);
1258
+ }
1259
+ return new DocumentTree("row", items);
1260
+ }
1261
+ static generateBox(rowProbability) {
1262
+ return new DocumentTree("box", DocumentTree.generateContent(rowProbability));
1263
+ }
1264
+ }
1265
+ exports.DocumentTree = DocumentTree;
1266
+ DocumentTree.randPack = new RandomPack();
1267
+ function findReplacePerf(filename) {
1268
+ const client = new testClient_1.TestClient();
1269
+ (0, testUtils_1.loadTextFromFile)(filename, client.mergeTree);
1270
+ const clockStart = clock();
1271
+ let cFetches = 0;
1272
+ let cReplaces = 0;
1273
+ for (let pos = 0; pos < client.getLength();) {
1274
+ const curSegOff = client.getContainingSegment(pos);
1275
+ cFetches++;
1276
+ const curSeg = curSegOff.segment;
1277
+ const textSeg = curSeg;
1278
+ if (textSeg !== null) {
1279
+ const text = textSeg.text;
1280
+ const i = text.indexOf("the");
1281
+ if (i >= 0) {
1282
+ client.mergeTree.markRangeRemoved(pos + i, pos + i + 3, constants_1.UniversalSequenceNumber, client.getClientId(), 1, false, undefined);
1283
+ (0, testUtils_1.insertText)({
1284
+ mergeTree: client.mergeTree,
1285
+ pos: pos + i,
1286
+ refSeq: constants_1.UniversalSequenceNumber,
1287
+ clientId: client.getClientId(),
1288
+ seq: 1,
1289
+ text: "teh",
1290
+ props: undefined,
1291
+ opArgs: undefined,
1292
+ });
1293
+ pos = pos + i + 3;
1294
+ cReplaces++;
1295
+ }
1296
+ else {
1297
+ pos += curSeg.cachedLength - curSegOff.offset;
1298
+ }
1299
+ }
1300
+ }
1301
+ const elapsed = elapsedMicroseconds(clockStart);
1302
+ log(`${cFetches} fetches and ${cReplaces} replaces took ${elapsed} microseconds`);
1303
+ }
1304
+ const baseDir = "../../src/test/literature";
1305
+ const testTimeout = 60000;
1306
+ describe("Routerlicious", () => {
1307
+ describe("merge-tree", () => {
1308
+ beforeEach(() => {
1309
+ logLines = [];
1310
+ });
1311
+ it("firstTest", () => {
1312
+ const testPack = TestPack(true);
1313
+ testPack.firstTest();
1314
+ });
1315
+ it("randolicious", () => {
1316
+ const testPack = TestPack(false);
1317
+ (0, assert_1.strict)(testPack.randolicious() === 0, logLines.join("\n"));
1318
+ }).timeout(testTimeout);
1319
+ it("mergeTreeCheckedTest", () => {
1320
+ (0, assert_1.strict)(mergeTreeCheckedTest() === 0, logLines.join("\n"));
1321
+ }).timeout(testTimeout);
1322
+ it("beastTest", () => {
1323
+ const testPack = TestPack(false);
1324
+ const filename = path_1.default.join(__dirname, baseDir, "pp.txt");
1325
+ (0, assert_1.strict)(testPack.clientServer(filename, 250) === 0, logLines.join("\n"));
1326
+ }).timeout(testTimeout);
1327
+ it("findReplPerf", () => {
1328
+ const filename = path_1.default.join(__dirname, baseDir, "pp10.txt");
1329
+ findReplacePerf(filename);
1330
+ }).timeout(testTimeout);
1331
+ });
1332
+ });
1333
+ //# sourceMappingURL=beastTest.js.map