@fluidframework/sequence 2.0.0-rc.1.0.6 → 2.0.0-rc.2.0.1

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 (379) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +4 -1
  2. package/{.mocharc.js → .mocharc.cjs} +1 -1
  3. package/CHANGELOG.md +8 -0
  4. package/README.md +2 -2
  5. package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
  6. package/api-extractor.json +1 -1
  7. package/api-report/sequence.api.md +15 -27
  8. package/dist/defaultMap.d.ts +10 -16
  9. package/dist/defaultMap.d.ts.map +1 -1
  10. package/dist/defaultMap.js +73 -70
  11. package/dist/defaultMap.js.map +1 -1
  12. package/dist/defaultMapInterfaces.d.ts +1 -8
  13. package/dist/defaultMapInterfaces.d.ts.map +1 -1
  14. package/dist/defaultMapInterfaces.js.map +1 -1
  15. package/dist/index.d.ts +11 -11
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +42 -42
  18. package/dist/index.js.map +1 -1
  19. package/dist/intervalCollection.d.ts +21 -15
  20. package/dist/intervalCollection.d.ts.map +1 -1
  21. package/dist/intervalCollection.js +59 -110
  22. package/dist/intervalCollection.js.map +1 -1
  23. package/dist/intervalIndex/endpointInRangeIndex.d.ts +3 -3
  24. package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
  25. package/dist/intervalIndex/endpointInRangeIndex.js +8 -8
  26. package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
  27. package/dist/intervalIndex/endpointIndex.d.ts +3 -3
  28. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
  29. package/dist/intervalIndex/endpointIndex.js +4 -4
  30. package/dist/intervalIndex/endpointIndex.js.map +1 -1
  31. package/dist/intervalIndex/idIntervalIndex.d.ts +2 -2
  32. package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -1
  33. package/dist/intervalIndex/idIntervalIndex.js +2 -2
  34. package/dist/intervalIndex/idIntervalIndex.js.map +1 -1
  35. package/dist/intervalIndex/index.d.ts +8 -8
  36. package/dist/intervalIndex/index.d.ts.map +1 -1
  37. package/dist/intervalIndex/index.js +16 -16
  38. package/dist/intervalIndex/index.js.map +1 -1
  39. package/dist/intervalIndex/intervalIndex.d.ts +1 -1
  40. package/dist/intervalIndex/intervalIndex.d.ts.map +1 -1
  41. package/dist/intervalIndex/intervalIndex.js.map +1 -1
  42. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +7 -10
  43. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  44. package/dist/intervalIndex/overlappingIntervalsIndex.js +9 -12
  45. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  46. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +2 -2
  47. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
  48. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +7 -7
  49. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
  50. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +2 -2
  51. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
  52. package/dist/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
  53. package/dist/intervalIndex/startpointInRangeIndex.d.ts +3 -3
  54. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  55. package/dist/intervalIndex/startpointInRangeIndex.js +8 -8
  56. package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
  57. package/dist/intervalTree.d.ts +1 -1
  58. package/dist/intervalTree.d.ts.map +1 -1
  59. package/dist/intervalTree.js.map +1 -1
  60. package/dist/intervals/index.d.ts +3 -3
  61. package/dist/intervals/index.d.ts.map +1 -1
  62. package/dist/intervals/index.js +16 -16
  63. package/dist/intervals/index.js.map +1 -1
  64. package/dist/intervals/interval.d.ts +2 -2
  65. package/dist/intervals/interval.d.ts.map +1 -1
  66. package/dist/intervals/interval.js +2 -2
  67. package/dist/intervals/interval.js.map +1 -1
  68. package/dist/intervals/intervalUtils.d.ts +3 -3
  69. package/dist/intervals/intervalUtils.d.ts.map +1 -1
  70. package/dist/intervals/intervalUtils.js +1 -1
  71. package/dist/intervals/intervalUtils.js.map +1 -1
  72. package/dist/intervals/sequenceInterval.d.ts +2 -2
  73. package/dist/intervals/sequenceInterval.d.ts.map +1 -1
  74. package/dist/intervals/sequenceInterval.js +22 -23
  75. package/dist/intervals/sequenceInterval.js.map +1 -1
  76. package/dist/localValues.d.ts +2 -2
  77. package/dist/localValues.d.ts.map +1 -1
  78. package/dist/localValues.js.map +1 -1
  79. package/dist/package.json +3 -0
  80. package/dist/packageVersion.d.ts +1 -1
  81. package/dist/packageVersion.js +1 -1
  82. package/dist/packageVersion.js.map +1 -1
  83. package/dist/revertibles.d.ts +12 -12
  84. package/dist/revertibles.d.ts.map +1 -1
  85. package/dist/revertibles.js +26 -26
  86. package/dist/revertibles.js.map +1 -1
  87. package/dist/sequence-alpha.d.ts +167 -13
  88. package/dist/sequence-beta.d.ts +2 -0
  89. package/dist/sequence-public.d.ts +2 -0
  90. package/dist/sequence-untrimmed.d.ts +68 -14
  91. package/dist/sequence.d.ts +43 -5
  92. package/dist/sequence.d.ts.map +1 -1
  93. package/dist/sequence.js +98 -29
  94. package/dist/sequence.js.map +1 -1
  95. package/dist/sequenceFactory.d.ts +4 -1
  96. package/dist/sequenceFactory.d.ts.map +1 -1
  97. package/dist/sequenceFactory.js +8 -5
  98. package/dist/sequenceFactory.js.map +1 -1
  99. package/dist/sharedIntervalCollection.d.ts +2 -2
  100. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  101. package/dist/sharedIntervalCollection.js +5 -5
  102. package/dist/sharedIntervalCollection.js.map +1 -1
  103. package/dist/sharedSequence.d.ts +1 -1
  104. package/dist/sharedSequence.d.ts.map +1 -1
  105. package/dist/sharedSequence.js +2 -2
  106. package/dist/sharedSequence.js.map +1 -1
  107. package/dist/sharedString.d.ts +2 -2
  108. package/dist/sharedString.d.ts.map +1 -1
  109. package/dist/sharedString.js +6 -6
  110. package/dist/sharedString.js.map +1 -1
  111. package/dist/tsdoc-metadata.json +1 -1
  112. package/lib/{defaultMap.d.mts → defaultMap.d.ts} +11 -17
  113. package/lib/defaultMap.d.ts.map +1 -0
  114. package/lib/{defaultMap.mjs → defaultMap.js} +72 -69
  115. package/lib/defaultMap.js.map +1 -0
  116. package/lib/{defaultMapInterfaces.d.mts → defaultMapInterfaces.d.ts} +2 -9
  117. package/lib/defaultMapInterfaces.d.ts.map +1 -0
  118. package/lib/{defaultMapInterfaces.mjs → defaultMapInterfaces.js} +1 -1
  119. package/lib/defaultMapInterfaces.js.map +1 -0
  120. package/lib/{index.d.mts → index.d.ts} +24 -12
  121. package/lib/index.d.ts.map +1 -0
  122. package/lib/{index.mjs → index.js} +11 -11
  123. package/lib/index.js.map +1 -0
  124. package/lib/{intervalCollection.d.mts → intervalCollection.d.ts} +22 -16
  125. package/lib/intervalCollection.d.ts.map +1 -0
  126. package/lib/{intervalCollection.mjs → intervalCollection.js} +23 -74
  127. package/lib/intervalCollection.js.map +1 -0
  128. package/lib/intervalIndex/{endpointInRangeIndex.d.mts → endpointInRangeIndex.d.ts} +4 -4
  129. package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -0
  130. package/lib/intervalIndex/{endpointInRangeIndex.mjs → endpointInRangeIndex.js} +3 -3
  131. package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -0
  132. package/lib/intervalIndex/{endpointIndex.d.mts → endpointIndex.d.ts} +4 -4
  133. package/lib/intervalIndex/endpointIndex.d.ts.map +1 -0
  134. package/lib/intervalIndex/{endpointIndex.mjs → endpointIndex.js} +2 -2
  135. package/lib/intervalIndex/endpointIndex.js.map +1 -0
  136. package/lib/intervalIndex/{idIntervalIndex.d.mts → idIntervalIndex.d.ts} +3 -3
  137. package/lib/intervalIndex/idIntervalIndex.d.ts.map +1 -0
  138. package/lib/intervalIndex/{idIntervalIndex.mjs → idIntervalIndex.js} +2 -2
  139. package/lib/intervalIndex/idIntervalIndex.js.map +1 -0
  140. package/lib/intervalIndex/{index.d.mts → index.d.ts} +9 -9
  141. package/lib/intervalIndex/index.d.ts.map +1 -0
  142. package/lib/intervalIndex/{index.mjs → index.js} +7 -7
  143. package/lib/intervalIndex/index.js.map +1 -0
  144. package/lib/intervalIndex/{intervalIndex.d.mts → intervalIndex.d.ts} +2 -2
  145. package/lib/intervalIndex/intervalIndex.d.ts.map +1 -0
  146. package/lib/intervalIndex/{intervalIndex.mjs → intervalIndex.js} +1 -1
  147. package/lib/intervalIndex/intervalIndex.js.map +1 -0
  148. package/lib/intervalIndex/{intervalIndexUtils.d.mts → intervalIndexUtils.d.ts} +1 -1
  149. package/lib/intervalIndex/intervalIndexUtils.d.ts.map +1 -0
  150. package/lib/intervalIndex/{intervalIndexUtils.mjs → intervalIndexUtils.js} +1 -1
  151. package/lib/intervalIndex/intervalIndexUtils.js.map +1 -0
  152. package/lib/intervalIndex/{overlappingIntervalsIndex.d.mts → overlappingIntervalsIndex.d.ts} +8 -11
  153. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
  154. package/lib/intervalIndex/{overlappingIntervalsIndex.mjs → overlappingIntervalsIndex.js} +5 -8
  155. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -0
  156. package/lib/intervalIndex/{overlappingSequenceIntervalsIndex.d.mts → overlappingSequenceIntervalsIndex.d.ts} +3 -3
  157. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
  158. package/lib/intervalIndex/{overlappingSequenceIntervalsIndex.mjs → overlappingSequenceIntervalsIndex.js} +3 -3
  159. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -0
  160. package/lib/intervalIndex/{sequenceIntervalIndexes.d.mts → sequenceIntervalIndexes.d.ts} +3 -3
  161. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
  162. package/lib/intervalIndex/{sequenceIntervalIndexes.mjs → sequenceIntervalIndexes.js} +1 -1
  163. package/lib/intervalIndex/sequenceIntervalIndexes.js.map +1 -0
  164. package/lib/intervalIndex/{startpointInRangeIndex.d.mts → startpointInRangeIndex.d.ts} +4 -4
  165. package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -0
  166. package/lib/intervalIndex/{startpointInRangeIndex.mjs → startpointInRangeIndex.js} +3 -3
  167. package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -0
  168. package/lib/{intervalTree.d.mts → intervalTree.d.ts} +2 -2
  169. package/lib/intervalTree.d.ts.map +1 -0
  170. package/lib/{intervalTree.mjs → intervalTree.js} +1 -1
  171. package/lib/intervalTree.js.map +1 -0
  172. package/lib/intervals/{index.d.mts → index.d.ts} +4 -4
  173. package/lib/intervals/index.d.ts.map +1 -0
  174. package/lib/intervals/{index.mjs → index.js} +4 -4
  175. package/lib/intervals/index.js.map +1 -0
  176. package/lib/intervals/{interval.d.mts → interval.d.ts} +3 -3
  177. package/lib/intervals/{interval.d.mts.map → interval.d.ts.map} +1 -1
  178. package/lib/intervals/{interval.mjs → interval.js} +2 -2
  179. package/lib/intervals/interval.js.map +1 -0
  180. package/lib/intervals/{intervalUtils.d.mts → intervalUtils.d.ts} +4 -4
  181. package/lib/intervals/intervalUtils.d.ts.map +1 -0
  182. package/lib/intervals/{intervalUtils.mjs → intervalUtils.js} +3 -2
  183. package/lib/intervals/intervalUtils.js.map +1 -0
  184. package/lib/intervals/{sequenceInterval.d.mts → sequenceInterval.d.ts} +3 -3
  185. package/lib/intervals/sequenceInterval.d.ts.map +1 -0
  186. package/lib/intervals/{sequenceInterval.mjs → sequenceInterval.js} +5 -4
  187. package/lib/intervals/{sequenceInterval.mjs.map → sequenceInterval.js.map} +1 -1
  188. package/lib/{localValues.d.mts → localValues.d.ts} +3 -3
  189. package/lib/{localValues.d.mts.map → localValues.d.ts.map} +1 -1
  190. package/lib/{localValues.mjs → localValues.js} +1 -1
  191. package/lib/localValues.js.map +1 -0
  192. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  193. package/lib/packageVersion.d.ts.map +1 -0
  194. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  195. package/lib/packageVersion.js.map +1 -0
  196. package/lib/{revertibles.d.mts → revertibles.d.ts} +13 -13
  197. package/lib/revertibles.d.ts.map +1 -0
  198. package/lib/{revertibles.mjs → revertibles.js} +11 -10
  199. package/lib/revertibles.js.map +1 -0
  200. package/lib/{sequence-alpha.d.mts → sequence-alpha.d.ts} +180 -13
  201. package/lib/{sequence-public.d.mts → sequence-beta.d.ts} +15 -0
  202. package/lib/{sequence-beta.d.mts → sequence-public.d.ts} +15 -0
  203. package/lib/{sequence-untrimmed.d.mts → sequence-untrimmed.d.ts} +81 -14
  204. package/lib/{sequence.d.mts → sequence.d.ts} +44 -6
  205. package/lib/sequence.d.ts.map +1 -0
  206. package/lib/{sequence.mjs → sequence.js} +95 -29
  207. package/lib/sequence.js.map +1 -0
  208. package/lib/{sequenceDeltaEvent.d.mts → sequenceDeltaEvent.d.ts} +1 -1
  209. package/lib/sequenceDeltaEvent.d.ts.map +1 -0
  210. package/lib/{sequenceDeltaEvent.mjs → sequenceDeltaEvent.js} +1 -1
  211. package/lib/sequenceDeltaEvent.js.map +1 -0
  212. package/lib/{sequenceFactory.d.mts → sequenceFactory.d.ts} +5 -2
  213. package/lib/sequenceFactory.d.ts.map +1 -0
  214. package/lib/{sequenceFactory.mjs → sequenceFactory.js} +6 -3
  215. package/lib/sequenceFactory.js.map +1 -0
  216. package/lib/{sharedIntervalCollection.d.mts → sharedIntervalCollection.d.ts} +3 -3
  217. package/lib/sharedIntervalCollection.d.ts.map +1 -0
  218. package/lib/{sharedIntervalCollection.mjs → sharedIntervalCollection.js} +4 -4
  219. package/lib/sharedIntervalCollection.js.map +1 -0
  220. package/lib/{sharedSequence.d.mts → sharedSequence.d.ts} +2 -2
  221. package/lib/sharedSequence.d.ts.map +1 -0
  222. package/lib/{sharedSequence.mjs → sharedSequence.js} +2 -2
  223. package/lib/sharedSequence.js.map +1 -0
  224. package/lib/{sharedString.d.mts → sharedString.d.ts} +3 -3
  225. package/lib/sharedString.d.ts.map +1 -0
  226. package/lib/{sharedString.mjs → sharedString.js} +3 -3
  227. package/lib/sharedString.js.map +1 -0
  228. package/lib/test/collections.intervalTree.js +73 -0
  229. package/lib/test/collections.intervalTree.js.map +1 -0
  230. package/lib/test/createSnapshotFiles.js +15 -0
  231. package/lib/test/createSnapshotFiles.js.map +1 -0
  232. package/lib/test/dirname.cjs +16 -0
  233. package/lib/test/dirname.cjs.map +1 -0
  234. package/lib/test/endpointInRangeIndex.spec.js +182 -0
  235. package/lib/test/endpointInRangeIndex.spec.js.map +1 -0
  236. package/lib/test/fuzz/fuzzUtils.js +250 -0
  237. package/lib/test/fuzz/fuzzUtils.js.map +1 -0
  238. package/lib/test/fuzz/intervalCollection.fuzz.spec.js +200 -0
  239. package/lib/test/fuzz/intervalCollection.fuzz.spec.js.map +1 -0
  240. package/lib/test/fuzz/intervalRevertibles.fuzz.spec.js +129 -0
  241. package/lib/test/fuzz/intervalRevertibles.fuzz.spec.js.map +1 -0
  242. package/lib/test/fuzz/sharedString.fuzz.spec.js +91 -0
  243. package/lib/test/fuzz/sharedString.fuzz.spec.js.map +1 -0
  244. package/lib/test/generateSharedStrings.js +138 -0
  245. package/lib/test/generateSharedStrings.js.map +1 -0
  246. package/lib/test/intervalCollection.detached.spec.js +126 -0
  247. package/lib/test/intervalCollection.detached.spec.js.map +1 -0
  248. package/lib/test/intervalCollection.events.spec.js +491 -0
  249. package/lib/test/intervalCollection.events.spec.js.map +1 -0
  250. package/lib/test/intervalCollection.perf.spec.js +88 -0
  251. package/lib/test/intervalCollection.perf.spec.js.map +1 -0
  252. package/lib/test/intervalCollection.snapshot.spec.js +171 -0
  253. package/lib/test/intervalCollection.snapshot.spec.js.map +1 -0
  254. package/lib/test/intervalCollection.spec.js +1660 -0
  255. package/lib/test/intervalCollection.spec.js.map +1 -0
  256. package/lib/test/intervalIndexTestUtils.js +49 -0
  257. package/lib/test/intervalIndexTestUtils.js.map +1 -0
  258. package/lib/test/intervalRebasing.spec.js +589 -0
  259. package/lib/test/intervalRebasing.spec.js.map +1 -0
  260. package/lib/test/intervalStashedOps.spec.js +142 -0
  261. package/lib/test/intervalStashedOps.spec.js.map +1 -0
  262. package/lib/test/intervalTestUtils.js +81 -0
  263. package/lib/test/intervalTestUtils.js.map +1 -0
  264. package/lib/test/marshalling.spec.js +55 -0
  265. package/lib/test/marshalling.spec.js.map +1 -0
  266. package/lib/test/memory/sharedSequence.spec.js +82 -0
  267. package/lib/test/memory/sharedSequence.spec.js.map +1 -0
  268. package/lib/test/memory/sharedString.spec.js +134 -0
  269. package/lib/test/memory/sharedString.spec.js.map +1 -0
  270. package/lib/test/overlappingSequenceIntervalsIndex.spec.js +348 -0
  271. package/lib/test/overlappingSequenceIntervalsIndex.spec.js.map +1 -0
  272. package/lib/test/partialLoad.spec.js +211 -0
  273. package/lib/test/partialLoad.spec.js.map +1 -0
  274. package/lib/test/rebasing.spec.js +81 -0
  275. package/lib/test/rebasing.spec.js.map +1 -0
  276. package/lib/test/reentrancy.spec.js +174 -0
  277. package/lib/test/reentrancy.spec.js.map +1 -0
  278. package/lib/test/revertibles.spec.js +971 -0
  279. package/lib/test/revertibles.spec.js.map +1 -0
  280. package/lib/test/sequenceDeltaEvent.spec.js +2144 -0
  281. package/lib/test/sequenceDeltaEvent.spec.js.map +1 -0
  282. package/lib/test/sharedIntervalCollection.spec.js +159 -0
  283. package/lib/test/sharedIntervalCollection.spec.js.map +1 -0
  284. package/lib/test/sharedString.spec.js +532 -0
  285. package/lib/test/sharedString.spec.js.map +1 -0
  286. package/lib/test/snapshotEmptyProps.spec.js +45 -0
  287. package/lib/test/snapshotEmptyProps.spec.js.map +1 -0
  288. package/lib/test/snapshotVersion.spec.js +149 -0
  289. package/lib/test/snapshotVersion.spec.js.map +1 -0
  290. package/lib/test/startpointInRangeIndex.spec.js +182 -0
  291. package/lib/test/startpointInRangeIndex.spec.js.map +1 -0
  292. package/lib/test/subSequence.spec.js +92 -0
  293. package/lib/test/subSequence.spec.js.map +1 -0
  294. package/lib/test/types/validateSequencePrevious.generated.js +162 -0
  295. package/lib/test/types/validateSequencePrevious.generated.js.map +1 -0
  296. package/lib/test/v1IntervalCollectionHelpers.js +93 -0
  297. package/lib/test/v1IntervalCollectionHelpers.js.map +1 -0
  298. package/package.json +66 -60
  299. package/src/defaultMap.ts +97 -123
  300. package/src/defaultMapInterfaces.ts +1 -9
  301. package/src/index.ts +15 -11
  302. package/src/intervalCollection.ts +57 -84
  303. package/src/intervalIndex/endpointInRangeIndex.ts +4 -4
  304. package/src/intervalIndex/endpointIndex.ts +3 -3
  305. package/src/intervalIndex/idIntervalIndex.ts +3 -4
  306. package/src/intervalIndex/index.ts +8 -8
  307. package/src/intervalIndex/intervalIndex.ts +1 -1
  308. package/src/intervalIndex/overlappingIntervalsIndex.ts +7 -10
  309. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +4 -4
  310. package/src/intervalIndex/sequenceIntervalIndexes.ts +2 -2
  311. package/src/intervalIndex/startpointInRangeIndex.ts +4 -4
  312. package/src/intervalTree.ts +1 -1
  313. package/src/intervals/index.ts +3 -3
  314. package/src/intervals/interval.ts +2 -4
  315. package/src/intervals/intervalUtils.ts +3 -3
  316. package/src/intervals/sequenceInterval.ts +3 -4
  317. package/src/localValues.ts +2 -2
  318. package/src/packageVersion.ts +1 -1
  319. package/src/revertibles.ts +13 -13
  320. package/src/sequence.ts +121 -44
  321. package/src/sequenceFactory.ts +5 -2
  322. package/src/sharedIntervalCollection.ts +5 -5
  323. package/src/sharedSequence.ts +1 -1
  324. package/src/sharedString.ts +2 -2
  325. package/tsconfig.cjs.json +7 -0
  326. package/tsconfig.json +2 -5
  327. package/lib/defaultMap.d.mts.map +0 -1
  328. package/lib/defaultMap.mjs.map +0 -1
  329. package/lib/defaultMapInterfaces.d.mts.map +0 -1
  330. package/lib/defaultMapInterfaces.mjs.map +0 -1
  331. package/lib/index.d.mts.map +0 -1
  332. package/lib/index.mjs.map +0 -1
  333. package/lib/intervalCollection.d.mts.map +0 -1
  334. package/lib/intervalCollection.mjs.map +0 -1
  335. package/lib/intervalIndex/endpointInRangeIndex.d.mts.map +0 -1
  336. package/lib/intervalIndex/endpointInRangeIndex.mjs.map +0 -1
  337. package/lib/intervalIndex/endpointIndex.d.mts.map +0 -1
  338. package/lib/intervalIndex/endpointIndex.mjs.map +0 -1
  339. package/lib/intervalIndex/idIntervalIndex.d.mts.map +0 -1
  340. package/lib/intervalIndex/idIntervalIndex.mjs.map +0 -1
  341. package/lib/intervalIndex/index.d.mts.map +0 -1
  342. package/lib/intervalIndex/index.mjs.map +0 -1
  343. package/lib/intervalIndex/intervalIndex.d.mts.map +0 -1
  344. package/lib/intervalIndex/intervalIndex.mjs.map +0 -1
  345. package/lib/intervalIndex/intervalIndexUtils.d.mts.map +0 -1
  346. package/lib/intervalIndex/intervalIndexUtils.mjs.map +0 -1
  347. package/lib/intervalIndex/overlappingIntervalsIndex.d.mts.map +0 -1
  348. package/lib/intervalIndex/overlappingIntervalsIndex.mjs.map +0 -1
  349. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts.map +0 -1
  350. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs.map +0 -1
  351. package/lib/intervalIndex/sequenceIntervalIndexes.d.mts.map +0 -1
  352. package/lib/intervalIndex/sequenceIntervalIndexes.mjs.map +0 -1
  353. package/lib/intervalIndex/startpointInRangeIndex.d.mts.map +0 -1
  354. package/lib/intervalIndex/startpointInRangeIndex.mjs.map +0 -1
  355. package/lib/intervalTree.d.mts.map +0 -1
  356. package/lib/intervalTree.mjs.map +0 -1
  357. package/lib/intervals/index.d.mts.map +0 -1
  358. package/lib/intervals/index.mjs.map +0 -1
  359. package/lib/intervals/interval.mjs.map +0 -1
  360. package/lib/intervals/intervalUtils.d.mts.map +0 -1
  361. package/lib/intervals/intervalUtils.mjs.map +0 -1
  362. package/lib/intervals/sequenceInterval.d.mts.map +0 -1
  363. package/lib/localValues.mjs.map +0 -1
  364. package/lib/packageVersion.d.mts.map +0 -1
  365. package/lib/packageVersion.mjs.map +0 -1
  366. package/lib/revertibles.d.mts.map +0 -1
  367. package/lib/revertibles.mjs.map +0 -1
  368. package/lib/sequence.d.mts.map +0 -1
  369. package/lib/sequence.mjs.map +0 -1
  370. package/lib/sequenceDeltaEvent.d.mts.map +0 -1
  371. package/lib/sequenceDeltaEvent.mjs.map +0 -1
  372. package/lib/sequenceFactory.d.mts.map +0 -1
  373. package/lib/sequenceFactory.mjs.map +0 -1
  374. package/lib/sharedIntervalCollection.d.mts.map +0 -1
  375. package/lib/sharedIntervalCollection.mjs.map +0 -1
  376. package/lib/sharedSequence.d.mts.map +0 -1
  377. package/lib/sharedSequence.mjs.map +0 -1
  378. package/lib/sharedString.d.mts.map +0 -1
  379. package/lib/sharedString.mjs.map +0 -1
@@ -0,0 +1,971 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { strict as assert } from "assert";
6
+ import { MockContainerRuntimeFactory, MockFluidDataStoreRuntime, MockStorage, } from "@fluidframework/test-runtime-utils";
7
+ import { AttachState } from "@fluidframework/container-definitions";
8
+ import { appendAddIntervalToRevertibles, appendChangeIntervalToRevertibles, appendDeleteIntervalToRevertibles, appendIntervalPropertyChangedToRevertibles, appendSharedStringDeltaToRevertibles, revertSharedStringRevertibles, } from "../revertibles.js";
9
+ import { SharedString } from "../sharedString.js";
10
+ import { Side } from "../intervalCollection.js";
11
+ import { SharedStringFactory } from "../sequenceFactory.js";
12
+ import { IntervalStickiness } from "../intervals/index.js";
13
+ import { assertSequenceIntervals } from "./intervalTestUtils.js";
14
+ describe("Sequence.Revertibles with Local Edits", () => {
15
+ let sharedString;
16
+ let dataStoreRuntime1;
17
+ let collection;
18
+ let revertibles;
19
+ let containerRuntimeFactory;
20
+ const stringFactory = new SharedStringFactory();
21
+ beforeEach(() => {
22
+ containerRuntimeFactory = new MockContainerRuntimeFactory();
23
+ dataStoreRuntime1 = new MockFluidDataStoreRuntime({ clientId: "1" });
24
+ dataStoreRuntime1.setAttachState(AttachState.Attached);
25
+ sharedString = stringFactory.create(dataStoreRuntime1, "shared-string-1");
26
+ const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
27
+ const services1 = {
28
+ deltaConnection: dataStoreRuntime1.createDeltaConnection(),
29
+ objectStorage: new MockStorage(),
30
+ };
31
+ sharedString.initializeLocal();
32
+ sharedString.connect(services1);
33
+ collection = sharedString.getIntervalCollection("test");
34
+ revertibles = [];
35
+ });
36
+ it("revert direct interval insert", () => {
37
+ collection.on("addInterval", (interval, local, op) => {
38
+ appendAddIntervalToRevertibles(interval, revertibles);
39
+ });
40
+ sharedString.insertText(0, "hello world");
41
+ collection.add({ start: 0, end: 5 });
42
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
43
+ assertSequenceIntervals(sharedString, collection, []);
44
+ });
45
+ it("revert direct interval remove", () => {
46
+ collection.on("deleteInterval", (interval, local, op) => {
47
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
48
+ });
49
+ sharedString.insertText(0, "hello world");
50
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
51
+ collection.removeIntervalById(id);
52
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
53
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
54
+ });
55
+ it("revert direct interval change", () => {
56
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
57
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
58
+ });
59
+ sharedString.insertText(0, "hello world");
60
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
61
+ collection.change(id, { start: 1, end: 6 });
62
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
63
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
64
+ });
65
+ it("revert direct interval property change", () => {
66
+ collection.on("propertyChanged", (interval, propertyDeltas, local, op) => {
67
+ appendIntervalPropertyChangedToRevertibles(interval, propertyDeltas, revertibles);
68
+ });
69
+ sharedString.insertText(0, "hello world");
70
+ const id = collection.add({ start: 0, end: 5, props: { foo: "one" } }).getIntervalId();
71
+ collection.change(id, { props: { foo: "two" } });
72
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
73
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
74
+ const int = collection.getIntervalById(id);
75
+ assert.equal(int?.properties.foo, "one");
76
+ });
77
+ it("reverts multiple interval adds", () => {
78
+ collection.on("addInterval", (interval, local, op) => {
79
+ appendAddIntervalToRevertibles(interval, revertibles);
80
+ });
81
+ sharedString.insertText(0, "hello world");
82
+ collection.add({ start: 0, end: 5 });
83
+ collection.add({ start: 5, end: 7 });
84
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
85
+ assertSequenceIntervals(sharedString, collection, []);
86
+ });
87
+ it("reverts multiple interval removes", () => {
88
+ collection.on("deleteInterval", (interval, local, op) => {
89
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
90
+ });
91
+ sharedString.insertText(0, "hello world");
92
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
93
+ const id2 = collection.add({ start: 5, end: 7 }).getIntervalId();
94
+ collection.removeIntervalById(id);
95
+ collection.removeIntervalById(id2);
96
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
97
+ assertSequenceIntervals(sharedString, collection, [
98
+ { start: 0, end: 5 },
99
+ { start: 5, end: 7 },
100
+ ]);
101
+ });
102
+ it("performs multiple reverts on the same interval", () => {
103
+ collection.on("addInterval", (interval, local, op) => {
104
+ appendAddIntervalToRevertibles(interval, revertibles);
105
+ });
106
+ collection.on("deleteInterval", (interval, local, op) => {
107
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
108
+ });
109
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
110
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
111
+ });
112
+ sharedString.insertText(0, "hello world");
113
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
114
+ collection.change(id, { start: 3, end: 8 });
115
+ collection.removeIntervalById(id);
116
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
117
+ assertSequenceIntervals(sharedString, collection, []);
118
+ });
119
+ it("performs two local changes, then reverts the first", () => {
120
+ collection.on("addInterval", (interval, local, op) => {
121
+ appendAddIntervalToRevertibles(interval, revertibles);
122
+ });
123
+ sharedString.insertText(0, "hello world");
124
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
125
+ collection.change(id, { start: 3, end: 8 });
126
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
127
+ assertSequenceIntervals(sharedString, collection, []);
128
+ });
129
+ it("checks that revert functions properly when an id is recreated on revert of a delete", () => {
130
+ sharedString.insertText(0, "hello world");
131
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
132
+ collection.on("deleteInterval", (interval, local, op) => {
133
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
134
+ });
135
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
136
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
137
+ });
138
+ collection.change(id, { start: 3, end: 8 });
139
+ collection.removeIntervalById(id);
140
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
141
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
142
+ });
143
+ it("checks that revertibles still finds correct interval across multiple remove and reverts", () => {
144
+ sharedString.insertText(0, "hello world");
145
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
146
+ collection.on("deleteInterval", (interval, local, op) => {
147
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
148
+ });
149
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
150
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
151
+ });
152
+ collection.change(id, { start: 3, end: 8 });
153
+ collection.removeIntervalById(id);
154
+ revertSharedStringRevertibles(sharedString, revertibles.splice(1, 1));
155
+ assertSequenceIntervals(sharedString, collection, [{ start: 3, end: 8 }]);
156
+ const intervals = Array.from(collection);
157
+ const removed = collection.removeIntervalById(intervals[0].getIntervalId());
158
+ assert(removed, "interval was not removed from the collection");
159
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
160
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
161
+ });
162
+ it("local only text remove, no ack, move interval out of range", () => {
163
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
164
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
165
+ });
166
+ sharedString.insertText(0, "hello world");
167
+ const id = collection.add({ start: 2, end: 4 }).getIntervalId();
168
+ containerRuntimeFactory.processAllMessages();
169
+ sharedString.removeRange(0, 5);
170
+ collection.change(id, { start: 1, end: 2 });
171
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
172
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 0 }]);
173
+ });
174
+ it("change interval out of removed range - local refs are out of range so revert should not happen", () => {
175
+ sharedString.insertText(0, "hello world");
176
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
177
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
178
+ });
179
+ const id = collection.add({ start: 5, end: 8 }).getIntervalId();
180
+ containerRuntimeFactory.processAllMessages();
181
+ collection.change(id, { start: 1, end: 3 });
182
+ sharedString.removeRange(5, sharedString.getLength());
183
+ containerRuntimeFactory.processAllMessages();
184
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
185
+ assertSequenceIntervals(sharedString, collection, [{ start: 4, end: 4 }]);
186
+ });
187
+ it("change interval into removed range - revert should move interval out of detached case into remaining string", () => {
188
+ sharedString.insertText(0, "hello world");
189
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
190
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
191
+ });
192
+ const id = collection.add({ start: 1, end: 3 }).getIntervalId();
193
+ containerRuntimeFactory.processAllMessages();
194
+ collection.change(id, { start: 4, end: 8 });
195
+ sharedString.removeRange(4, sharedString.getLength());
196
+ containerRuntimeFactory.processAllMessages();
197
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
198
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 3 }]);
199
+ });
200
+ });
201
+ describe("Sequence.Revertibles with Remote Edits", () => {
202
+ let sharedString;
203
+ let dataStoreRuntime1;
204
+ let collection;
205
+ let collection2;
206
+ let revertibles;
207
+ let sharedString2;
208
+ let containerRuntimeFactory;
209
+ beforeEach(() => {
210
+ dataStoreRuntime1 = new MockFluidDataStoreRuntime({ clientId: "1" });
211
+ sharedString = new SharedString(dataStoreRuntime1, "shared-string-1", SharedStringFactory.Attributes);
212
+ containerRuntimeFactory = new MockContainerRuntimeFactory();
213
+ // Connect the first SharedString.
214
+ dataStoreRuntime1.setAttachState(AttachState.Attached);
215
+ const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
216
+ const services1 = {
217
+ deltaConnection: dataStoreRuntime1.createDeltaConnection(),
218
+ objectStorage: new MockStorage(),
219
+ };
220
+ sharedString.initializeLocal();
221
+ sharedString.connect(services1);
222
+ // Create and connect a second SharedString.
223
+ const dataStoreRuntime2 = new MockFluidDataStoreRuntime({ clientId: "2" });
224
+ const containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);
225
+ const services2 = {
226
+ deltaConnection: dataStoreRuntime2.createDeltaConnection(),
227
+ objectStorage: new MockStorage(),
228
+ };
229
+ sharedString2 = new SharedString(dataStoreRuntime2, "shared-string-2", SharedStringFactory.Attributes);
230
+ sharedString2.initializeLocal();
231
+ sharedString2.connect(services2);
232
+ revertibles = [];
233
+ collection = sharedString.getIntervalCollection("test");
234
+ collection2 = sharedString2.getIntervalCollection("test");
235
+ });
236
+ it("interval change, range remove, ack, revert change interval", () => {
237
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
238
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
239
+ });
240
+ sharedString.insertText(0, "hello world");
241
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
242
+ containerRuntimeFactory.processAllMessages();
243
+ collection.change(id, { start: 6, end: 8 });
244
+ sharedString2.removeRange(0, 5);
245
+ containerRuntimeFactory.processAllMessages();
246
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
247
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 0 }]);
248
+ containerRuntimeFactory.processAllMessages();
249
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 0 }]);
250
+ });
251
+ it("remote string remove interacting with reverting an interval remove", () => {
252
+ collection.on("deleteInterval", (interval, local, op) => {
253
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
254
+ });
255
+ sharedString.insertText(0, "hello world");
256
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
257
+ collection.removeIntervalById(id);
258
+ containerRuntimeFactory.processAllMessages();
259
+ sharedString2.removeRange(1, 3);
260
+ containerRuntimeFactory.processAllMessages();
261
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
262
+ containerRuntimeFactory.processAllMessages();
263
+ assert.equal(sharedString.getText(), sharedString2.getText());
264
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 3 }]);
265
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 3 }]);
266
+ });
267
+ it("remote string remove that shares an endpoint with a removed interval that gets reverted", () => {
268
+ collection.on("deleteInterval", (interval, local, op) => {
269
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
270
+ });
271
+ sharedString.insertText(0, "hello world");
272
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
273
+ collection.removeIntervalById(id);
274
+ containerRuntimeFactory.processAllMessages();
275
+ sharedString2.removeRange(0, 3);
276
+ containerRuntimeFactory.processAllMessages();
277
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
278
+ containerRuntimeFactory.processAllMessages();
279
+ assert.equal(sharedString.getText(), sharedString2.getText());
280
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 2 }]);
281
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 2 }]);
282
+ });
283
+ it("remote string add interacting with reverting an interval remove", () => {
284
+ collection.on("deleteInterval", (interval, local, op) => {
285
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
286
+ });
287
+ sharedString.insertText(0, "hello world");
288
+ const id = collection.add({ start: 0, end: 7 }).getIntervalId();
289
+ containerRuntimeFactory.processAllMessages();
290
+ collection.removeIntervalById(id);
291
+ sharedString2.insertText(5, " hi");
292
+ containerRuntimeFactory.processAllMessages();
293
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
294
+ containerRuntimeFactory.processAllMessages();
295
+ assert.equal(sharedString.getText(), sharedString2.getText());
296
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 10 }]);
297
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 10 }]);
298
+ });
299
+ it("remote interval change interacting with reverting an interval remove", () => {
300
+ sharedString.insertText(0, "hello world");
301
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
302
+ containerRuntimeFactory.processAllMessages();
303
+ collection2.change(id, { start: 3, end: 8 });
304
+ collection.on("deleteInterval", (interval, local, op) => {
305
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
306
+ });
307
+ collection.removeIntervalById(id);
308
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
309
+ containerRuntimeFactory.processAllMessages();
310
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
311
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
312
+ });
313
+ it("remote interval change interacting with reverting an interval remove with ack before revert", () => {
314
+ sharedString.insertText(0, "hello world");
315
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
316
+ containerRuntimeFactory.processAllMessages();
317
+ collection2.change(id, { start: 3, end: 8 });
318
+ collection.on("deleteInterval", (interval, local, op) => {
319
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
320
+ });
321
+ collection.removeIntervalById(id);
322
+ containerRuntimeFactory.processAllMessages();
323
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
324
+ containerRuntimeFactory.processAllMessages();
325
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
326
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
327
+ });
328
+ it("acked remote interval change interacting with reverting an interval change", () => {
329
+ sharedString.insertText(0, "hello world");
330
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
331
+ containerRuntimeFactory.processAllMessages();
332
+ collection2.change(id, { start: 3, end: 8 });
333
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
334
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
335
+ });
336
+ collection.change(id, { start: 4, end: 9 });
337
+ containerRuntimeFactory.processOneMessage();
338
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
339
+ containerRuntimeFactory.processAllMessages();
340
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
341
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
342
+ });
343
+ it("remote interval remove interacting with reverting an interval change", () => {
344
+ sharedString.insertText(0, "hello world");
345
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
346
+ containerRuntimeFactory.processAllMessages();
347
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
348
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
349
+ });
350
+ collection.change(id, { start: 3, end: 8 });
351
+ containerRuntimeFactory.processAllMessages();
352
+ collection2.removeIntervalById(id);
353
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
354
+ containerRuntimeFactory.processAllMessages();
355
+ assertSequenceIntervals(sharedString, collection, []);
356
+ assertSequenceIntervals(sharedString2, collection2, []);
357
+ });
358
+ it("remote interval remove interacting with reverting an interval property change", () => {
359
+ sharedString.insertText(0, "hello world");
360
+ const id = collection.add({ start: 0, end: 5, props: { foo: "one" } }).getIntervalId();
361
+ containerRuntimeFactory.processAllMessages();
362
+ collection.on("propertyChanged", (interval, propertyDeltas, local, op) => {
363
+ appendIntervalPropertyChangedToRevertibles(interval, propertyDeltas, revertibles);
364
+ });
365
+ collection.change(id, { props: { foo: "two" } });
366
+ collection2.removeIntervalById(id);
367
+ containerRuntimeFactory.processAllMessages();
368
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
369
+ containerRuntimeFactory.processAllMessages();
370
+ assertSequenceIntervals(sharedString, collection, []);
371
+ assertSequenceIntervals(sharedString2, collection2, []);
372
+ });
373
+ it("remote interval remove interacting with reverting an interval remove", () => {
374
+ sharedString.insertText(0, "hello world");
375
+ const id = collection.add({ start: 0, end: 5 }).getIntervalId();
376
+ containerRuntimeFactory.processAllMessages();
377
+ collection.on("deleteInterval", (interval, local, op) => {
378
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
379
+ });
380
+ collection.removeIntervalById(id);
381
+ collection2.removeIntervalById(id);
382
+ containerRuntimeFactory.processAllMessages();
383
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
384
+ containerRuntimeFactory.processAllMessages();
385
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
386
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
387
+ });
388
+ it("remote interval property change interacting with reverting an interval remove", () => {
389
+ sharedString.insertText(0, "hello world");
390
+ const id = collection.add({ start: 0, end: 5, props: { foo: "one" } }).getIntervalId();
391
+ containerRuntimeFactory.processAllMessages();
392
+ collection.on("deleteInterval", (interval, local, op) => {
393
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
394
+ });
395
+ collection.removeIntervalById(id);
396
+ collection2.change(id, { props: { foo: "two" } });
397
+ containerRuntimeFactory.processAllMessages();
398
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
399
+ containerRuntimeFactory.processAllMessages();
400
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
401
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
402
+ const intervals = Array.from(collection);
403
+ assert.equal(intervals[0].properties.foo, "one");
404
+ });
405
+ it("remote interval property change interacting with reverting an interval add", () => {
406
+ sharedString.insertText(0, "hello world");
407
+ const id = collection.add({ start: 0, end: 5, props: { foo: "one" } }).getIntervalId();
408
+ containerRuntimeFactory.processAllMessages();
409
+ collection.on("addInterval", (interval, local, op) => {
410
+ appendAddIntervalToRevertibles(interval, revertibles);
411
+ });
412
+ collection.add({ start: 2, end: 7 });
413
+ collection2.change(id, { props: { foo: "two" } });
414
+ containerRuntimeFactory.processAllMessages();
415
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
416
+ containerRuntimeFactory.processAllMessages();
417
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
418
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
419
+ const int = collection.getIntervalById(id);
420
+ assert.equal(int?.properties.foo, "two");
421
+ });
422
+ it("remote interval property change interacting with reverting an interval change", () => {
423
+ sharedString.insertText(0, "hello world");
424
+ const id = collection.add({ start: 0, end: 5, props: { foo: "one" } }).getIntervalId();
425
+ containerRuntimeFactory.processAllMessages();
426
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
427
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
428
+ });
429
+ collection.change(id, { start: 3, end: 8 });
430
+ collection2.change(id, { props: { foo: "two" } });
431
+ containerRuntimeFactory.processAllMessages();
432
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
433
+ containerRuntimeFactory.processAllMessages();
434
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
435
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
436
+ const int = collection.getIntervalById(id);
437
+ assert.equal(int?.properties.foo, "two");
438
+ });
439
+ it("remote interval property change interacting with reverting an interval property change", () => {
440
+ sharedString.insertText(0, "hello world");
441
+ const id = collection.add({ start: 0, end: 5, props: { foo: "one" } }).getIntervalId();
442
+ containerRuntimeFactory.processAllMessages();
443
+ collection.on("propertyChanged", (interval, propertyDeltas, local, op) => {
444
+ if (local) {
445
+ appendIntervalPropertyChangedToRevertibles(interval, propertyDeltas, revertibles);
446
+ }
447
+ });
448
+ collection.change(id, { props: { foo: "two", bar: "one" } });
449
+ collection2.change(id, { props: { foo: "three", bar: "one" } });
450
+ containerRuntimeFactory.processAllMessages();
451
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
452
+ containerRuntimeFactory.processAllMessages();
453
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 5 }]);
454
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 0, end: 5 }]);
455
+ const int = collection.getIntervalById(id);
456
+ assert.equal(int?.properties.foo, "one");
457
+ assert.equal(int?.properties.bar, undefined);
458
+ });
459
+ });
460
+ describe("Undo/redo for string remove containing intervals", () => {
461
+ let sharedString;
462
+ let dataStoreRuntime1;
463
+ let containerRuntimeFactory;
464
+ let collection;
465
+ let revertibles;
466
+ beforeEach(() => {
467
+ dataStoreRuntime1 = new MockFluidDataStoreRuntime({ clientId: "1" });
468
+ sharedString = new SharedString(dataStoreRuntime1, "shared-string-1", SharedStringFactory.Attributes);
469
+ containerRuntimeFactory = new MockContainerRuntimeFactory();
470
+ // Connect the first SharedString.
471
+ dataStoreRuntime1.setAttachState(AttachState.Attached);
472
+ const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
473
+ const services1 = {
474
+ deltaConnection: dataStoreRuntime1.createDeltaConnection(),
475
+ objectStorage: new MockStorage(),
476
+ };
477
+ sharedString.initializeLocal();
478
+ sharedString.connect(services1);
479
+ collection = sharedString.getIntervalCollection("test");
480
+ revertibles = [];
481
+ });
482
+ describe("with remote ops", () => {
483
+ let sharedString2;
484
+ let collection2;
485
+ beforeEach(() => {
486
+ const dataStoreRuntime2 = new MockFluidDataStoreRuntime({ clientId: "2" });
487
+ const containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);
488
+ const services2 = {
489
+ deltaConnection: dataStoreRuntime2.createDeltaConnection(),
490
+ objectStorage: new MockStorage(),
491
+ };
492
+ sharedString2 = new SharedString(dataStoreRuntime2, "shared-string-2", SharedStringFactory.Attributes);
493
+ sharedString2.initializeLocal();
494
+ sharedString2.connect(services2);
495
+ collection2 = sharedString2.getIntervalCollection("test");
496
+ });
497
+ it("handles remote remove of same range", () => {
498
+ sharedString.insertText(0, "hello world");
499
+ sharedString.on("sequenceDelta", (op) => {
500
+ if (op.isLocal) {
501
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
502
+ }
503
+ });
504
+ const int = collection.add({ start: 2, end: 4 });
505
+ containerRuntimeFactory.processAllMessages();
506
+ sharedString2.removeRange(0, 6);
507
+ sharedString.removeRange(0, 6);
508
+ assert.equal(sharedString.getText(), "world");
509
+ assert.equal(sharedString2.getText(), "world");
510
+ containerRuntimeFactory.processAllMessages();
511
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
512
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
513
+ assert.equal(sharedString.getText(), "hello world");
514
+ assertSequenceIntervals(sharedString, collection, [{ start: 2, end: 4 }]);
515
+ containerRuntimeFactory.processAllMessages();
516
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 2, end: 4 }]);
517
+ });
518
+ it("ignores remote interval move", () => {
519
+ sharedString.insertText(0, "hello world");
520
+ sharedString.on("sequenceDelta", (op) => {
521
+ if (op.isLocal) {
522
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
523
+ }
524
+ });
525
+ const interval = collection.add({ start: 2, end: 4 });
526
+ containerRuntimeFactory.processAllMessages();
527
+ sharedString.removeRange(0, 6);
528
+ sharedString2
529
+ .getIntervalCollection("test")
530
+ .change(interval.getIntervalId(), { start: 3, end: 8 });
531
+ containerRuntimeFactory.processAllMessages();
532
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
533
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
534
+ assert.equal(sharedString.getText(), "hello world");
535
+ // start moved within deleted range is restored, end moved outside is not
536
+ assertSequenceIntervals(sharedString, collection, [{ start: 2, end: 4 }]);
537
+ containerRuntimeFactory.processAllMessages();
538
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 2, end: 4 }]);
539
+ });
540
+ it("handles remote interval delete", () => {
541
+ sharedString.insertText(0, "hello world");
542
+ sharedString.on("sequenceDelta", (op) => {
543
+ if (op.isLocal) {
544
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
545
+ }
546
+ });
547
+ const interval = collection.add({ start: 2, end: 4 });
548
+ containerRuntimeFactory.processAllMessages();
549
+ sharedString.removeRange(0, 6);
550
+ sharedString2
551
+ .getIntervalCollection("test")
552
+ .removeIntervalById(interval.getIntervalId());
553
+ containerRuntimeFactory.processAllMessages();
554
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
555
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
556
+ assert.equal(sharedString.getText(), "hello world");
557
+ assertSequenceIntervals(sharedString, collection, []);
558
+ containerRuntimeFactory.processAllMessages();
559
+ assertSequenceIntervals(sharedString2, collection2, []);
560
+ });
561
+ it("handles remote interval move with one contained endpoint", () => {
562
+ sharedString.insertText(0, "hello world");
563
+ sharedString.on("sequenceDelta", (op) => {
564
+ if (op.isLocal) {
565
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
566
+ }
567
+ });
568
+ const interval = collection.add({ start: 6, end: 8 });
569
+ containerRuntimeFactory.processAllMessages();
570
+ sharedString2
571
+ .getIntervalCollection("test")
572
+ .change(interval.getIntervalId(), { start: 1, end: 9 });
573
+ sharedString.removeRange(5, 7);
574
+ containerRuntimeFactory.processAllMessages();
575
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
576
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
577
+ assert.equal(sharedString.getText(), "hello world");
578
+ assertSequenceIntervals(sharedString, collection, [{ start: 6, end: 9 }]);
579
+ containerRuntimeFactory.processAllMessages();
580
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 6, end: 9 }]);
581
+ });
582
+ it("does not restore start that would be after end", () => {
583
+ sharedString.insertText(0, "hello world");
584
+ sharedString.on("sequenceDelta", (op) => {
585
+ if (op.isLocal) {
586
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
587
+ }
588
+ });
589
+ const interval = collection.add({ start: 6, end: 8 });
590
+ containerRuntimeFactory.processAllMessages();
591
+ sharedString2
592
+ .getIntervalCollection("test")
593
+ .change(interval.getIntervalId(), { start: 1, end: 3 });
594
+ sharedString.removeRange(5, 7);
595
+ containerRuntimeFactory.processAllMessages();
596
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
597
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
598
+ assert.equal(sharedString.getText(), "hello world");
599
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 3 }]);
600
+ containerRuntimeFactory.processAllMessages();
601
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 1, end: 3 }]);
602
+ });
603
+ it("does not restore end that would be before start", () => {
604
+ sharedString.insertText(0, "hello world");
605
+ sharedString.on("sequenceDelta", (op) => {
606
+ if (op.isLocal) {
607
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
608
+ }
609
+ });
610
+ const interval = collection.add({ start: 4, end: 6 });
611
+ containerRuntimeFactory.processAllMessages();
612
+ sharedString2
613
+ .getIntervalCollection("test")
614
+ .change(interval.getIntervalId(), { start: 8, end: 9 });
615
+ sharedString.removeRange(5, 7);
616
+ containerRuntimeFactory.processAllMessages();
617
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
618
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
619
+ assert.equal(sharedString.getText(), "hello world");
620
+ assertSequenceIntervals(sharedString, collection, [{ start: 8, end: 9 }]);
621
+ containerRuntimeFactory.processAllMessages();
622
+ assertSequenceIntervals(sharedString2, collection2, [{ start: 8, end: 9 }]);
623
+ });
624
+ });
625
+ it("has an interval contained within the deleted range", () => {
626
+ sharedString.insertText(0, "hello world");
627
+ sharedString.on("sequenceDelta", (op) => {
628
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
629
+ });
630
+ const interval = collection.add({ start: 2, end: 4 });
631
+ sharedString.removeRange(0, 6);
632
+ const actualStart = sharedString.localReferencePositionToPosition(interval.start);
633
+ const actualEnd = sharedString.localReferencePositionToPosition(interval.end);
634
+ assert.equal(actualStart, 0, `actualStart is ${actualStart}`);
635
+ assert.equal(actualEnd, 0, `actualEnd is ${actualEnd}`);
636
+ assert.equal(revertibles.length, 1, "revertibles.length is not 1");
637
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
638
+ assert.equal(sharedString.getText(), "hello world");
639
+ assertSequenceIntervals(sharedString, collection, [{ start: 2, end: 4 }]);
640
+ assert.equal(interval.start.getOffset(), 2, `after remove start.getOffset() is ${interval.start.getOffset()}`);
641
+ assert.equal(interval.end.getOffset(), 4, `after remove start.getOffset() is ${interval.end.getOffset()}`);
642
+ });
643
+ it("has an interval with endpoints at the deleted range", () => {
644
+ sharedString.insertText(0, "hello world");
645
+ sharedString.on("sequenceDelta", (op) => {
646
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
647
+ });
648
+ collection.add({ start: 0, end: 6 });
649
+ sharedString.removeRange(0, 6);
650
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
651
+ assert.equal(sharedString.getText(), "hello world");
652
+ assertSequenceIntervals(sharedString, collection, [{ start: 0, end: 6 }]);
653
+ });
654
+ it("has an interval with one endpoint within the deleted range", () => {
655
+ sharedString.insertText(0, "hello world");
656
+ sharedString.on("sequenceDelta", (op) => {
657
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
658
+ });
659
+ collection.add({ start: 5, end: 9 });
660
+ sharedString.removeRange(2, 7);
661
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
662
+ assert.equal(sharedString.getText(), "hello world");
663
+ assertSequenceIntervals(sharedString, collection, [{ start: 5, end: 9 }]);
664
+ });
665
+ it("restores an interval after two removes", () => {
666
+ sharedString.insertText(0, "hello world");
667
+ sharedString.on("sequenceDelta", (op) => {
668
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
669
+ });
670
+ collection.add({ start: 3, end: 6 });
671
+ // only one revertible object generated for both removes
672
+ sharedString.removeRange(1, 4);
673
+ sharedString.removeRange(3, 6);
674
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
675
+ assert.equal(sharedString.getText(), "hello world");
676
+ assertSequenceIntervals(sharedString, collection, [{ start: 3, end: 6 }]);
677
+ });
678
+ it("reverts an ack'ed remove", () => {
679
+ sharedString.insertText(0, "hello world");
680
+ sharedString.on("sequenceDelta", (op) => {
681
+ if (op.opArgs.sequencedMessage === undefined) {
682
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
683
+ }
684
+ });
685
+ collection.add({ start: 5, end: 9 });
686
+ sharedString.removeRange(2, 7);
687
+ containerRuntimeFactory.processAllMessages();
688
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
689
+ assert.equal(sharedString.getText(), "hello world");
690
+ assertSequenceIntervals(sharedString, collection, [{ start: 5, end: 9 }]);
691
+ });
692
+ it("has multiple interval endpoints within the deleted range", () => {
693
+ sharedString.insertText(0, "hello world");
694
+ sharedString.on("sequenceDelta", (op) => {
695
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
696
+ });
697
+ collection.add({ start: 5, end: 9 });
698
+ collection.add({ start: 0, end: 3 });
699
+ collection.add({ start: 3, end: 4 });
700
+ sharedString.removeRange(2, 7);
701
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
702
+ assert.equal(sharedString.getText(), "hello world");
703
+ assertSequenceIntervals(sharedString, collection, [
704
+ { start: 0, end: 3 },
705
+ { start: 3, end: 4 },
706
+ { start: 5, end: 9 },
707
+ ]);
708
+ });
709
+ it("has an interval across two segments in the deleted range", () => {
710
+ sharedString.insertText(0, "world");
711
+ sharedString.insertText(0, "hello ");
712
+ sharedString.on("sequenceDelta", (op) => {
713
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
714
+ });
715
+ collection.add({ start: 3, end: 7 });
716
+ sharedString.removeRange(2, 8);
717
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
718
+ assert.equal(sharedString.getText(), "hello world");
719
+ assertSequenceIntervals(sharedString, collection, [{ start: 3, end: 7 }]);
720
+ });
721
+ it("has multiple intervals across two segments in the deleted range", () => {
722
+ sharedString.insertText(0, "world");
723
+ sharedString.insertText(0, "hello ");
724
+ sharedString.on("sequenceDelta", (op) => {
725
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
726
+ });
727
+ collection.add({ start: 3, end: 7 });
728
+ collection.add({ start: 0, end: 6 });
729
+ sharedString.removeRange(2, 8);
730
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
731
+ assert.equal(sharedString.getText(), "hello world");
732
+ assertSequenceIntervals(sharedString, collection, [
733
+ { start: 0, end: 6 },
734
+ { start: 3, end: 7 },
735
+ ]);
736
+ });
737
+ describe("mixed with direct interval edit revertibles", () => {
738
+ it("reverts interval delete + remove range", () => {
739
+ sharedString.insertText(0, "hello world");
740
+ const id = collection.add({ start: 1, end: 5 }).getIntervalId();
741
+ sharedString.on("sequenceDelta", (op) => {
742
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
743
+ });
744
+ collection.on("deleteInterval", (interval, local, op) => {
745
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
746
+ });
747
+ collection.removeIntervalById(id);
748
+ sharedString.removeRange(0, 8);
749
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
750
+ assert.equal(sharedString.getText(), "hello world");
751
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 5 }]);
752
+ });
753
+ it("reverts remove range + interval delete", () => {
754
+ sharedString.insertText(0, "hello world");
755
+ const id = collection.add({ start: 1, end: 5 }).getIntervalId();
756
+ sharedString.on("sequenceDelta", (op) => {
757
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
758
+ });
759
+ collection.on("deleteInterval", (interval, local, op) => {
760
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
761
+ });
762
+ sharedString.removeRange(0, 8);
763
+ collection.removeIntervalById(id);
764
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
765
+ assert.equal(sharedString.getText(), "hello world");
766
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 5 }]);
767
+ });
768
+ it("reverts interval change + remove range", () => {
769
+ sharedString.insertText(0, "hello world");
770
+ const id = collection.add({ start: 1, end: 5 }).getIntervalId();
771
+ sharedString.on("sequenceDelta", (op) => {
772
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
773
+ });
774
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
775
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
776
+ });
777
+ collection.change(id, { start: 2, end: 4 });
778
+ sharedString.removeRange(0, 8);
779
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
780
+ assert.equal(sharedString.getText(), "hello world");
781
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 5 }]);
782
+ });
783
+ it("reverts interval change + remove range with interval start", () => {
784
+ sharedString.insertText(0, "hello world");
785
+ const id = collection.add({ start: 1, end: 5 }).getIntervalId();
786
+ sharedString.on("sequenceDelta", (op) => {
787
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
788
+ });
789
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
790
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
791
+ });
792
+ collection.change(id, { start: 2, end: 9 });
793
+ sharedString.removeRange(0, 8);
794
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
795
+ assert.equal(sharedString.getText(), "hello world");
796
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 5 }]);
797
+ });
798
+ it("reverts interval change + remove range containing only revertible refs", () => {
799
+ sharedString.insertText(0, "hello world");
800
+ const id = collection.add({ start: 1, end: 5 }).getIntervalId();
801
+ sharedString.on("sequenceDelta", (op) => {
802
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
803
+ });
804
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
805
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
806
+ });
807
+ collection.change(id, { start: 9, end: 10 });
808
+ sharedString.removeRange(0, 8);
809
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
810
+ assert.equal(sharedString.getText(), "hello world");
811
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 5 }]);
812
+ });
813
+ it("reverts remove range + interval change", () => {
814
+ sharedString.insertText(0, "hello world");
815
+ const id = collection.add({ start: 1, end: 5 }).getIntervalId();
816
+ sharedString.on("sequenceDelta", (op) => {
817
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
818
+ });
819
+ collection.on("changeInterval", (interval, previousInterval, local, op) => {
820
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
821
+ });
822
+ sharedString.removeRange(0, 8);
823
+ collection.change(id, { start: 1, end: 2 });
824
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
825
+ assert.equal(sharedString.getText(), "hello world");
826
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 5 }]);
827
+ });
828
+ });
829
+ });
830
+ describe("Sequence.Revertibles with stickiness", () => {
831
+ let sharedString;
832
+ let dataStoreRuntime1;
833
+ let collection;
834
+ let revertibles;
835
+ let containerRuntimeFactory;
836
+ const stringFactory = new SharedStringFactory();
837
+ beforeEach(() => {
838
+ containerRuntimeFactory = new MockContainerRuntimeFactory();
839
+ dataStoreRuntime1 = new MockFluidDataStoreRuntime({ clientId: "1" });
840
+ dataStoreRuntime1.setAttachState(AttachState.Attached);
841
+ dataStoreRuntime1.options = {
842
+ intervalStickinessEnabled: true,
843
+ mergeTreeReferencesCanSlideToEndpoint: true,
844
+ };
845
+ sharedString = stringFactory.create(dataStoreRuntime1, "shared-string-1");
846
+ const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
847
+ const services1 = {
848
+ deltaConnection: containerRuntime1.createDeltaConnection(),
849
+ objectStorage: new MockStorage(),
850
+ };
851
+ sharedString.initializeLocal();
852
+ sharedString.connect(services1);
853
+ collection = sharedString.getIntervalCollection("test");
854
+ revertibles = [];
855
+ });
856
+ it("fails to revert interval remove of stickiness reversed endpoints", () => {
857
+ collection.on("deleteInterval", (interval) => {
858
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
859
+ });
860
+ sharedString.insertText(0, "hello world");
861
+ const id = collection
862
+ .add({
863
+ start: { pos: 5, side: Side.After },
864
+ end: { pos: 5, side: Side.Before },
865
+ })
866
+ .getIntervalId();
867
+ collection.removeIntervalById(id);
868
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
869
+ assertSequenceIntervals(sharedString, collection, []);
870
+ });
871
+ it("fails to revert interval change to stickiness reversed endpoints", () => {
872
+ collection.on("changeInterval", (interval, previousInterval) => {
873
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
874
+ });
875
+ sharedString.insertText(0, "hello world");
876
+ const id = collection
877
+ .add({
878
+ start: { pos: 5, side: Side.After },
879
+ end: { pos: 5, side: Side.Before },
880
+ })
881
+ .getIntervalId();
882
+ collection.change(id, { start: 1, end: 6 });
883
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
884
+ assertSequenceIntervals(sharedString, collection, [{ start: 1, end: 6 }]);
885
+ });
886
+ it("reverts remove range that reverses endpoints", () => {
887
+ sharedString.insertText(0, "hello world");
888
+ sharedString.on("sequenceDelta", (op) => {
889
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
890
+ });
891
+ const id = collection
892
+ .add({
893
+ start: { pos: 4, side: Side.Before },
894
+ end: { pos: 5, side: Side.After },
895
+ })
896
+ .getIntervalId();
897
+ sharedString.removeText(3, 6);
898
+ containerRuntimeFactory.processAllMessages();
899
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
900
+ const intervals = Array.from(collection);
901
+ assert.equal(intervals.length, 1, `wrong number of intervals ${intervals.length}`);
902
+ const int = intervals[0];
903
+ assert.equal(int.stickiness, IntervalStickiness.NONE, `unexpected stickiness ${int.stickiness}`);
904
+ const start = sharedString.localReferencePositionToPosition(int.start);
905
+ const end = sharedString.localReferencePositionToPosition(int.end);
906
+ assert.equal(start, 4, `start is ${start}`);
907
+ assert.equal(end, 5, `end is ${end}`);
908
+ });
909
+ it("reverts stickiness on interval remove", () => {
910
+ collection.on("deleteInterval", (interval) => {
911
+ appendDeleteIntervalToRevertibles(sharedString, interval, revertibles);
912
+ });
913
+ sharedString.insertText(0, "hello world");
914
+ const id = collection
915
+ .add({
916
+ start: { pos: 4, side: Side.After },
917
+ end: { pos: 5, side: Side.After },
918
+ })
919
+ .getIntervalId();
920
+ collection.removeIntervalById(id);
921
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
922
+ const intervals = Array.from(collection);
923
+ assert.equal(intervals.length, 1, `wrong number of intervals ${intervals.length}`);
924
+ const int = intervals[0];
925
+ assert.equal(int.stickiness, IntervalStickiness.START, `unexpected stickiness ${int.stickiness}`);
926
+ assert.equal(int.startSide, Side.After, "start side is Before");
927
+ assert.equal(int.endSide, Side.After, "end side is Before");
928
+ });
929
+ it("reverts stickiness on interval change", () => {
930
+ collection.on("changeInterval", (interval, previousInterval) => {
931
+ appendChangeIntervalToRevertibles(sharedString, interval, previousInterval, revertibles);
932
+ });
933
+ sharedString.insertText(0, "hello world");
934
+ const id = collection
935
+ .add({
936
+ start: { pos: 4, side: Side.After },
937
+ end: { pos: 5, side: Side.After },
938
+ })
939
+ .getIntervalId();
940
+ collection.change(id, {
941
+ start: { pos: 1, side: Side.Before },
942
+ end: { pos: 6, side: Side.Before },
943
+ });
944
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
945
+ const int = collection.getIntervalById(id);
946
+ assert.notEqual(int, undefined, "no interval");
947
+ assert.equal(int?.stickiness, IntervalStickiness.START, `unexpected stickiness ${int?.stickiness}`);
948
+ assert.equal(int.startSide, Side.After, "start side is Before");
949
+ assert.equal(int.endSide, Side.After, "end side is Before");
950
+ });
951
+ it("preserves stickiness on remove range", () => {
952
+ sharedString.insertText(0, "hello world");
953
+ sharedString.on("sequenceDelta", (op) => {
954
+ appendSharedStringDeltaToRevertibles(sharedString, op, revertibles);
955
+ });
956
+ const id = collection
957
+ .add({
958
+ start: { pos: 2, side: Side.After },
959
+ end: { pos: 4, side: Side.After },
960
+ })
961
+ .getIntervalId();
962
+ sharedString.removeRange(0, 6);
963
+ revertSharedStringRevertibles(sharedString, revertibles.splice(0));
964
+ const interval = collection.getIntervalById(id);
965
+ assert.notEqual(interval, undefined, "no interval");
966
+ assert.equal(interval?.stickiness, IntervalStickiness.START, `unexpected stickiness ${interval?.stickiness}`);
967
+ assert.equal(interval.startSide, Side.After, "start side is Before");
968
+ assert.equal(interval.endSide, Side.After, "end side is Before");
969
+ });
970
+ });
971
+ //# sourceMappingURL=revertibles.spec.js.map