@fluidframework/sequence 2.0.0-dev-rc.1.0.0.232845 → 2.0.0-dev-rc.2.0.0.246488

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 (388) hide show
  1. package/.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 +14 -27
  8. package/dist/{localValues.d.ts → IntervalCollectionValues.d.ts} +13 -12
  9. package/dist/IntervalCollectionValues.d.ts.map +1 -0
  10. package/dist/{localValues.js → IntervalCollectionValues.js} +4 -4
  11. package/dist/IntervalCollectionValues.js.map +1 -0
  12. package/dist/index.d.ts +11 -11
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +42 -42
  15. package/dist/index.js.map +1 -1
  16. package/dist/intervalCollection.d.ts +15 -22
  17. package/dist/intervalCollection.d.ts.map +1 -1
  18. package/dist/intervalCollection.js +53 -108
  19. package/dist/intervalCollection.js.map +1 -1
  20. package/dist/{defaultMap.d.ts → intervalCollectionMap.d.ts} +18 -57
  21. package/dist/intervalCollectionMap.d.ts.map +1 -0
  22. package/dist/{defaultMap.js → intervalCollectionMap.js} +77 -129
  23. package/dist/intervalCollectionMap.js.map +1 -0
  24. package/{lib/defaultMapInterfaces.d.mts → dist/intervalCollectionMapInterfaces.d.ts} +16 -22
  25. package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -0
  26. package/dist/{defaultMapInterfaces.js → intervalCollectionMapInterfaces.js} +1 -1
  27. package/dist/intervalCollectionMapInterfaces.js.map +1 -0
  28. package/dist/intervalIndex/endpointInRangeIndex.d.ts +3 -3
  29. package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
  30. package/dist/intervalIndex/endpointInRangeIndex.js +9 -9
  31. package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
  32. package/dist/intervalIndex/endpointIndex.d.ts +3 -3
  33. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
  34. package/dist/intervalIndex/endpointIndex.js +5 -5
  35. package/dist/intervalIndex/endpointIndex.js.map +1 -1
  36. package/dist/intervalIndex/idIntervalIndex.d.ts +2 -2
  37. package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -1
  38. package/dist/intervalIndex/idIntervalIndex.js +2 -2
  39. package/dist/intervalIndex/idIntervalIndex.js.map +1 -1
  40. package/dist/intervalIndex/index.d.ts +8 -8
  41. package/dist/intervalIndex/index.d.ts.map +1 -1
  42. package/dist/intervalIndex/index.js +16 -16
  43. package/dist/intervalIndex/index.js.map +1 -1
  44. package/dist/intervalIndex/intervalIndex.d.ts +1 -1
  45. package/dist/intervalIndex/intervalIndex.d.ts.map +1 -1
  46. package/dist/intervalIndex/intervalIndex.js.map +1 -1
  47. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +7 -10
  48. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  49. package/dist/intervalIndex/overlappingIntervalsIndex.js +12 -14
  50. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  51. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +2 -2
  52. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
  53. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +8 -8
  54. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
  55. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +2 -2
  56. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
  57. package/dist/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
  58. package/dist/intervalIndex/startpointInRangeIndex.d.ts +3 -3
  59. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  60. package/dist/intervalIndex/startpointInRangeIndex.js +9 -9
  61. package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
  62. package/dist/intervalTree.d.ts +1 -1
  63. package/dist/intervalTree.d.ts.map +1 -1
  64. package/dist/intervalTree.js.map +1 -1
  65. package/dist/intervals/index.d.ts +3 -3
  66. package/dist/intervals/index.d.ts.map +1 -1
  67. package/dist/intervals/index.js +16 -16
  68. package/dist/intervals/index.js.map +1 -1
  69. package/dist/intervals/interval.d.ts +2 -2
  70. package/dist/intervals/interval.d.ts.map +1 -1
  71. package/dist/intervals/interval.js +3 -3
  72. package/dist/intervals/interval.js.map +1 -1
  73. package/dist/intervals/intervalUtils.d.ts +3 -3
  74. package/dist/intervals/intervalUtils.d.ts.map +1 -1
  75. package/dist/intervals/intervalUtils.js +1 -1
  76. package/dist/intervals/intervalUtils.js.map +1 -1
  77. package/dist/intervals/sequenceInterval.d.ts +2 -2
  78. package/dist/intervals/sequenceInterval.d.ts.map +1 -1
  79. package/dist/intervals/sequenceInterval.js +22 -23
  80. package/dist/intervals/sequenceInterval.js.map +1 -1
  81. package/dist/package.json +3 -0
  82. package/dist/packageVersion.d.ts +1 -1
  83. package/dist/packageVersion.js +1 -1
  84. package/dist/packageVersion.js.map +1 -1
  85. package/dist/revertibles.d.ts +12 -12
  86. package/dist/revertibles.d.ts.map +1 -1
  87. package/dist/revertibles.js +26 -26
  88. package/dist/revertibles.js.map +1 -1
  89. package/dist/sequence-alpha.d.ts +149 -13
  90. package/dist/sequence-beta.d.ts +2 -0
  91. package/dist/sequence-public.d.ts +2 -0
  92. package/dist/sequence-untrimmed.d.ts +50 -14
  93. package/dist/sequence.d.ts +38 -5
  94. package/dist/sequence.d.ts.map +1 -1
  95. package/dist/sequence.js +79 -35
  96. package/dist/sequence.js.map +1 -1
  97. package/dist/sequenceFactory.d.ts +4 -1
  98. package/dist/sequenceFactory.d.ts.map +1 -1
  99. package/dist/sequenceFactory.js +8 -5
  100. package/dist/sequenceFactory.js.map +1 -1
  101. package/dist/sharedIntervalCollection.d.ts +2 -2
  102. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  103. package/dist/sharedIntervalCollection.js +5 -5
  104. package/dist/sharedIntervalCollection.js.map +1 -1
  105. package/dist/sharedSequence.d.ts +1 -1
  106. package/dist/sharedSequence.d.ts.map +1 -1
  107. package/dist/sharedSequence.js +2 -2
  108. package/dist/sharedSequence.js.map +1 -1
  109. package/dist/sharedString.d.ts +2 -2
  110. package/dist/sharedString.d.ts.map +1 -1
  111. package/dist/sharedString.js +6 -6
  112. package/dist/sharedString.js.map +1 -1
  113. package/dist/tsdoc-metadata.json +1 -1
  114. package/lib/{localValues.d.mts → IntervalCollectionValues.d.ts} +13 -12
  115. package/lib/IntervalCollectionValues.d.ts.map +1 -0
  116. package/lib/{localValues.mjs → IntervalCollectionValues.js} +2 -2
  117. package/lib/IntervalCollectionValues.js.map +1 -0
  118. package/lib/{index.d.mts → index.d.ts} +24 -12
  119. package/lib/index.d.ts.map +1 -0
  120. package/lib/{index.mjs → index.js} +11 -11
  121. package/lib/index.js.map +1 -0
  122. package/lib/{intervalCollection.d.mts → intervalCollection.d.ts} +16 -23
  123. package/lib/intervalCollection.d.ts.map +1 -0
  124. package/lib/{intervalCollection.mjs → intervalCollection.js} +17 -72
  125. package/lib/intervalCollection.js.map +1 -0
  126. package/lib/{defaultMap.d.mts → intervalCollectionMap.d.ts} +18 -57
  127. package/lib/intervalCollectionMap.d.ts.map +1 -0
  128. package/lib/{defaultMap.mjs → intervalCollectionMap.js} +75 -127
  129. package/lib/intervalCollectionMap.js.map +1 -0
  130. package/{dist/defaultMapInterfaces.d.ts → lib/intervalCollectionMapInterfaces.d.ts} +16 -22
  131. package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -0
  132. package/lib/{intervalIndex/sequenceIntervalIndexes.mjs → intervalCollectionMapInterfaces.js} +1 -1
  133. package/lib/intervalCollectionMapInterfaces.js.map +1 -0
  134. package/lib/intervalIndex/{endpointInRangeIndex.d.mts → endpointInRangeIndex.d.ts} +4 -4
  135. package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -0
  136. package/lib/intervalIndex/{endpointInRangeIndex.mjs → endpointInRangeIndex.js} +3 -3
  137. package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -0
  138. package/lib/intervalIndex/{endpointIndex.d.mts → endpointIndex.d.ts} +4 -4
  139. package/lib/intervalIndex/endpointIndex.d.ts.map +1 -0
  140. package/lib/intervalIndex/{endpointIndex.mjs → endpointIndex.js} +2 -2
  141. package/lib/intervalIndex/endpointIndex.js.map +1 -0
  142. package/lib/intervalIndex/{idIntervalIndex.d.mts → idIntervalIndex.d.ts} +3 -3
  143. package/lib/intervalIndex/idIntervalIndex.d.ts.map +1 -0
  144. package/lib/intervalIndex/{idIntervalIndex.mjs → idIntervalIndex.js} +2 -2
  145. package/lib/intervalIndex/idIntervalIndex.js.map +1 -0
  146. package/lib/intervalIndex/{index.d.mts → index.d.ts} +9 -9
  147. package/lib/intervalIndex/index.d.ts.map +1 -0
  148. package/lib/intervalIndex/{index.mjs → index.js} +7 -7
  149. package/lib/intervalIndex/index.js.map +1 -0
  150. package/lib/intervalIndex/{intervalIndex.d.mts → intervalIndex.d.ts} +2 -2
  151. package/lib/intervalIndex/intervalIndex.d.ts.map +1 -0
  152. package/lib/intervalIndex/{intervalIndex.mjs → intervalIndex.js} +1 -1
  153. package/lib/intervalIndex/intervalIndex.js.map +1 -0
  154. package/lib/intervalIndex/{intervalIndexUtils.d.mts → intervalIndexUtils.d.ts} +1 -1
  155. package/lib/intervalIndex/intervalIndexUtils.d.ts.map +1 -0
  156. package/lib/intervalIndex/{intervalIndexUtils.mjs → intervalIndexUtils.js} +1 -1
  157. package/lib/intervalIndex/intervalIndexUtils.js.map +1 -0
  158. package/lib/intervalIndex/{overlappingIntervalsIndex.d.mts → overlappingIntervalsIndex.d.ts} +8 -11
  159. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
  160. package/lib/intervalIndex/{overlappingIntervalsIndex.mjs → overlappingIntervalsIndex.js} +8 -10
  161. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -0
  162. package/lib/intervalIndex/{overlappingSequenceIntervalsIndex.d.mts → overlappingSequenceIntervalsIndex.d.ts} +3 -3
  163. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
  164. package/lib/intervalIndex/{overlappingSequenceIntervalsIndex.mjs → overlappingSequenceIntervalsIndex.js} +3 -3
  165. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -0
  166. package/lib/intervalIndex/{sequenceIntervalIndexes.d.mts → sequenceIntervalIndexes.d.ts} +3 -3
  167. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
  168. package/lib/{defaultMapInterfaces.mjs → intervalIndex/sequenceIntervalIndexes.js} +1 -1
  169. package/lib/intervalIndex/sequenceIntervalIndexes.js.map +1 -0
  170. package/lib/intervalIndex/{startpointInRangeIndex.d.mts → startpointInRangeIndex.d.ts} +4 -4
  171. package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -0
  172. package/lib/intervalIndex/{startpointInRangeIndex.mjs → startpointInRangeIndex.js} +3 -3
  173. package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -0
  174. package/lib/{intervalTree.d.mts → intervalTree.d.ts} +2 -2
  175. package/lib/intervalTree.d.ts.map +1 -0
  176. package/lib/{intervalTree.mjs → intervalTree.js} +1 -1
  177. package/lib/intervalTree.js.map +1 -0
  178. package/lib/intervals/{index.d.mts → index.d.ts} +4 -4
  179. package/lib/intervals/index.d.ts.map +1 -0
  180. package/lib/intervals/{index.mjs → index.js} +4 -4
  181. package/lib/intervals/index.js.map +1 -0
  182. package/lib/intervals/{interval.d.mts → interval.d.ts} +3 -3
  183. package/lib/intervals/{interval.d.mts.map → interval.d.ts.map} +1 -1
  184. package/lib/intervals/{interval.mjs → interval.js} +2 -2
  185. package/lib/intervals/interval.js.map +1 -0
  186. package/lib/intervals/{intervalUtils.d.mts → intervalUtils.d.ts} +4 -4
  187. package/lib/intervals/intervalUtils.d.ts.map +1 -0
  188. package/lib/intervals/{intervalUtils.mjs → intervalUtils.js} +3 -2
  189. package/lib/intervals/intervalUtils.js.map +1 -0
  190. package/lib/intervals/{sequenceInterval.d.mts → sequenceInterval.d.ts} +3 -3
  191. package/lib/intervals/sequenceInterval.d.ts.map +1 -0
  192. package/lib/intervals/{sequenceInterval.mjs → sequenceInterval.js} +5 -4
  193. package/lib/intervals/{sequenceInterval.mjs.map → sequenceInterval.js.map} +1 -1
  194. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  195. package/lib/packageVersion.d.ts.map +1 -0
  196. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  197. package/lib/packageVersion.js.map +1 -0
  198. package/lib/{revertibles.d.mts → revertibles.d.ts} +13 -13
  199. package/lib/revertibles.d.ts.map +1 -0
  200. package/lib/{revertibles.mjs → revertibles.js} +11 -10
  201. package/lib/revertibles.js.map +1 -0
  202. package/lib/{sequence-alpha.d.mts → sequence-alpha.d.ts} +162 -13
  203. package/lib/{sequence-beta.d.mts → sequence-beta.d.ts} +15 -0
  204. package/lib/{sequence-public.d.mts → sequence-public.d.ts} +15 -0
  205. package/lib/{sequence-untrimmed.d.mts → sequence-untrimmed.d.ts} +63 -14
  206. package/lib/{sequence.d.mts → sequence.d.ts} +39 -6
  207. package/lib/sequence.d.ts.map +1 -0
  208. package/lib/{sequence.mjs → sequence.js} +78 -34
  209. package/lib/sequence.js.map +1 -0
  210. package/lib/{sequenceDeltaEvent.d.mts → sequenceDeltaEvent.d.ts} +1 -1
  211. package/lib/sequenceDeltaEvent.d.ts.map +1 -0
  212. package/lib/{sequenceDeltaEvent.mjs → sequenceDeltaEvent.js} +1 -1
  213. package/lib/sequenceDeltaEvent.js.map +1 -0
  214. package/lib/{sequenceFactory.d.mts → sequenceFactory.d.ts} +5 -2
  215. package/lib/sequenceFactory.d.ts.map +1 -0
  216. package/lib/{sequenceFactory.mjs → sequenceFactory.js} +6 -3
  217. package/lib/sequenceFactory.js.map +1 -0
  218. package/lib/{sharedIntervalCollection.d.mts → sharedIntervalCollection.d.ts} +3 -3
  219. package/lib/sharedIntervalCollection.d.ts.map +1 -0
  220. package/lib/{sharedIntervalCollection.mjs → sharedIntervalCollection.js} +5 -5
  221. package/lib/sharedIntervalCollection.js.map +1 -0
  222. package/lib/{sharedSequence.d.mts → sharedSequence.d.ts} +2 -2
  223. package/lib/sharedSequence.d.ts.map +1 -0
  224. package/lib/{sharedSequence.mjs → sharedSequence.js} +2 -2
  225. package/lib/sharedSequence.js.map +1 -0
  226. package/lib/{sharedString.d.mts → sharedString.d.ts} +3 -3
  227. package/lib/sharedString.d.ts.map +1 -0
  228. package/lib/{sharedString.mjs → sharedString.js} +3 -3
  229. package/lib/sharedString.js.map +1 -0
  230. package/lib/test/collections.intervalTree.js +73 -0
  231. package/lib/test/collections.intervalTree.js.map +1 -0
  232. package/lib/test/createSnapshotFiles.js +15 -0
  233. package/lib/test/createSnapshotFiles.js.map +1 -0
  234. package/lib/test/dirname.cjs +16 -0
  235. package/lib/test/dirname.cjs.map +1 -0
  236. package/lib/test/endpointInRangeIndex.spec.js +182 -0
  237. package/lib/test/endpointInRangeIndex.spec.js.map +1 -0
  238. package/lib/test/fuzz/fuzzUtils.js +362 -0
  239. package/lib/test/fuzz/fuzzUtils.js.map +1 -0
  240. package/lib/test/fuzz/intervalCollection.fuzz.spec.js +87 -0
  241. package/lib/test/fuzz/intervalCollection.fuzz.spec.js.map +1 -0
  242. package/lib/test/fuzz/intervalRevertibles.fuzz.spec.js +128 -0
  243. package/lib/test/fuzz/intervalRevertibles.fuzz.spec.js.map +1 -0
  244. package/lib/test/fuzz/sharedString.fuzz.spec.js +91 -0
  245. package/lib/test/fuzz/sharedString.fuzz.spec.js.map +1 -0
  246. package/lib/test/generateSharedStrings.js +138 -0
  247. package/lib/test/generateSharedStrings.js.map +1 -0
  248. package/lib/test/intervalCollection.detached.spec.js +128 -0
  249. package/lib/test/intervalCollection.detached.spec.js.map +1 -0
  250. package/lib/test/intervalCollection.events.spec.js +491 -0
  251. package/lib/test/intervalCollection.events.spec.js.map +1 -0
  252. package/lib/test/intervalCollection.perf.spec.js +88 -0
  253. package/lib/test/intervalCollection.perf.spec.js.map +1 -0
  254. package/lib/test/intervalCollection.snapshot.spec.js +171 -0
  255. package/lib/test/intervalCollection.snapshot.spec.js.map +1 -0
  256. package/lib/test/intervalCollection.spec.js +1660 -0
  257. package/lib/test/intervalCollection.spec.js.map +1 -0
  258. package/lib/test/intervalIndexTestUtils.js +49 -0
  259. package/lib/test/intervalIndexTestUtils.js.map +1 -0
  260. package/lib/test/intervalRebasing.spec.js +589 -0
  261. package/lib/test/intervalRebasing.spec.js.map +1 -0
  262. package/lib/test/intervalStashedOps.spec.js +142 -0
  263. package/lib/test/intervalStashedOps.spec.js.map +1 -0
  264. package/lib/test/intervalTestUtils.js +81 -0
  265. package/lib/test/intervalTestUtils.js.map +1 -0
  266. package/lib/test/marshalling.spec.js +55 -0
  267. package/lib/test/marshalling.spec.js.map +1 -0
  268. package/lib/test/memory/sharedSequence.spec.js +82 -0
  269. package/lib/test/memory/sharedSequence.spec.js.map +1 -0
  270. package/lib/test/memory/sharedString.spec.js +134 -0
  271. package/lib/test/memory/sharedString.spec.js.map +1 -0
  272. package/lib/test/overlappingSequenceIntervalsIndex.spec.js +348 -0
  273. package/lib/test/overlappingSequenceIntervalsIndex.spec.js.map +1 -0
  274. package/lib/test/partialLoad.spec.js +211 -0
  275. package/lib/test/partialLoad.spec.js.map +1 -0
  276. package/lib/test/rebasing.spec.js +81 -0
  277. package/lib/test/rebasing.spec.js.map +1 -0
  278. package/lib/test/reentrancy.spec.js +174 -0
  279. package/lib/test/reentrancy.spec.js.map +1 -0
  280. package/lib/test/revertibles.spec.js +1019 -0
  281. package/lib/test/revertibles.spec.js.map +1 -0
  282. package/lib/test/sequenceDeltaEvent.spec.js +2144 -0
  283. package/lib/test/sequenceDeltaEvent.spec.js.map +1 -0
  284. package/lib/test/sharedIntervalCollection.spec.js +159 -0
  285. package/lib/test/sharedIntervalCollection.spec.js.map +1 -0
  286. package/lib/test/sharedString.spec.js +532 -0
  287. package/lib/test/sharedString.spec.js.map +1 -0
  288. package/lib/test/snapshotEmptyProps.spec.js +45 -0
  289. package/lib/test/snapshotEmptyProps.spec.js.map +1 -0
  290. package/lib/test/snapshotVersion.spec.js +149 -0
  291. package/lib/test/snapshotVersion.spec.js.map +1 -0
  292. package/lib/test/startpointInRangeIndex.spec.js +182 -0
  293. package/lib/test/startpointInRangeIndex.spec.js.map +1 -0
  294. package/lib/test/subSequence.spec.js +92 -0
  295. package/lib/test/subSequence.spec.js.map +1 -0
  296. package/lib/test/types/validateSequencePrevious.generated.js +162 -0
  297. package/lib/test/types/validateSequencePrevious.generated.js.map +1 -0
  298. package/lib/test/v1IntervalCollectionHelpers.js +93 -0
  299. package/lib/test/v1IntervalCollectionHelpers.js.map +1 -0
  300. package/package.json +64 -60
  301. package/src/{localValues.ts → IntervalCollectionValues.ts} +23 -17
  302. package/src/index.ts +15 -11
  303. package/src/intervalCollection.ts +37 -104
  304. package/src/{defaultMap.ts → intervalCollectionMap.ts} +120 -211
  305. package/src/{defaultMapInterfaces.ts → intervalCollectionMapInterfaces.ts} +24 -23
  306. package/src/intervalIndex/endpointInRangeIndex.ts +5 -4
  307. package/src/intervalIndex/endpointIndex.ts +4 -3
  308. package/src/intervalIndex/idIntervalIndex.ts +3 -4
  309. package/src/intervalIndex/index.ts +8 -8
  310. package/src/intervalIndex/intervalIndex.ts +1 -1
  311. package/src/intervalIndex/overlappingIntervalsIndex.ts +11 -11
  312. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +5 -4
  313. package/src/intervalIndex/sequenceIntervalIndexes.ts +2 -2
  314. package/src/intervalIndex/startpointInRangeIndex.ts +5 -4
  315. package/src/intervalTree.ts +1 -1
  316. package/src/intervals/index.ts +3 -3
  317. package/src/intervals/interval.ts +3 -4
  318. package/src/intervals/intervalUtils.ts +3 -3
  319. package/src/intervals/sequenceInterval.ts +3 -4
  320. package/src/packageVersion.ts +1 -1
  321. package/src/revertibles.ts +13 -13
  322. package/src/sequence.ts +101 -55
  323. package/src/sequenceFactory.ts +5 -2
  324. package/src/sharedIntervalCollection.ts +7 -11
  325. package/src/sharedSequence.ts +1 -1
  326. package/src/sharedString.ts +2 -2
  327. package/tsconfig.cjs.json +7 -0
  328. package/tsconfig.json +2 -5
  329. package/dist/defaultMap.d.ts.map +0 -1
  330. package/dist/defaultMap.js.map +0 -1
  331. package/dist/defaultMapInterfaces.d.ts.map +0 -1
  332. package/dist/defaultMapInterfaces.js.map +0 -1
  333. package/dist/localValues.d.ts.map +0 -1
  334. package/dist/localValues.js.map +0 -1
  335. package/lib/defaultMap.d.mts.map +0 -1
  336. package/lib/defaultMap.mjs.map +0 -1
  337. package/lib/defaultMapInterfaces.d.mts.map +0 -1
  338. package/lib/defaultMapInterfaces.mjs.map +0 -1
  339. package/lib/index.d.mts.map +0 -1
  340. package/lib/index.mjs.map +0 -1
  341. package/lib/intervalCollection.d.mts.map +0 -1
  342. package/lib/intervalCollection.mjs.map +0 -1
  343. package/lib/intervalIndex/endpointInRangeIndex.d.mts.map +0 -1
  344. package/lib/intervalIndex/endpointInRangeIndex.mjs.map +0 -1
  345. package/lib/intervalIndex/endpointIndex.d.mts.map +0 -1
  346. package/lib/intervalIndex/endpointIndex.mjs.map +0 -1
  347. package/lib/intervalIndex/idIntervalIndex.d.mts.map +0 -1
  348. package/lib/intervalIndex/idIntervalIndex.mjs.map +0 -1
  349. package/lib/intervalIndex/index.d.mts.map +0 -1
  350. package/lib/intervalIndex/index.mjs.map +0 -1
  351. package/lib/intervalIndex/intervalIndex.d.mts.map +0 -1
  352. package/lib/intervalIndex/intervalIndex.mjs.map +0 -1
  353. package/lib/intervalIndex/intervalIndexUtils.d.mts.map +0 -1
  354. package/lib/intervalIndex/intervalIndexUtils.mjs.map +0 -1
  355. package/lib/intervalIndex/overlappingIntervalsIndex.d.mts.map +0 -1
  356. package/lib/intervalIndex/overlappingIntervalsIndex.mjs.map +0 -1
  357. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts.map +0 -1
  358. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs.map +0 -1
  359. package/lib/intervalIndex/sequenceIntervalIndexes.d.mts.map +0 -1
  360. package/lib/intervalIndex/sequenceIntervalIndexes.mjs.map +0 -1
  361. package/lib/intervalIndex/startpointInRangeIndex.d.mts.map +0 -1
  362. package/lib/intervalIndex/startpointInRangeIndex.mjs.map +0 -1
  363. package/lib/intervalTree.d.mts.map +0 -1
  364. package/lib/intervalTree.mjs.map +0 -1
  365. package/lib/intervals/index.d.mts.map +0 -1
  366. package/lib/intervals/index.mjs.map +0 -1
  367. package/lib/intervals/interval.mjs.map +0 -1
  368. package/lib/intervals/intervalUtils.d.mts.map +0 -1
  369. package/lib/intervals/intervalUtils.mjs.map +0 -1
  370. package/lib/intervals/sequenceInterval.d.mts.map +0 -1
  371. package/lib/localValues.d.mts.map +0 -1
  372. package/lib/localValues.mjs.map +0 -1
  373. package/lib/packageVersion.d.mts.map +0 -1
  374. package/lib/packageVersion.mjs.map +0 -1
  375. package/lib/revertibles.d.mts.map +0 -1
  376. package/lib/revertibles.mjs.map +0 -1
  377. package/lib/sequence.d.mts.map +0 -1
  378. package/lib/sequence.mjs.map +0 -1
  379. package/lib/sequenceDeltaEvent.d.mts.map +0 -1
  380. package/lib/sequenceDeltaEvent.mjs.map +0 -1
  381. package/lib/sequenceFactory.d.mts.map +0 -1
  382. package/lib/sequenceFactory.mjs.map +0 -1
  383. package/lib/sharedIntervalCollection.d.mts.map +0 -1
  384. package/lib/sharedIntervalCollection.mjs.map +0 -1
  385. package/lib/sharedSequence.d.mts.map +0 -1
  386. package/lib/sharedSequence.mjs.map +0 -1
  387. package/lib/sharedString.d.mts.map +0 -1
  388. package/lib/sharedString.mjs.map +0 -1
@@ -0,0 +1,589 @@
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 { MockContainerRuntimeFactoryForReconnection, MockFluidDataStoreRuntime, MockStorage, } from "@fluidframework/test-runtime-utils";
7
+ // eslint-disable-next-line import/no-internal-modules
8
+ import { useStrictPartialLengthChecks } from "@fluidframework/merge-tree/test";
9
+ import { SharedString } from "../sharedString.js";
10
+ import { IntervalStickiness } from "../intervals/index.js";
11
+ import { Side } from "../intervalCollection.js";
12
+ import { SharedStringFactory } from "../sequenceFactory.js";
13
+ import { assertConsistent, assertSequenceIntervals } from "./intervalTestUtils.js";
14
+ function constructClient(containerRuntimeFactory, id) {
15
+ const dataStoreRuntime = new MockFluidDataStoreRuntime();
16
+ dataStoreRuntime.options = {
17
+ intervalStickinessEnabled: true,
18
+ mergeTreeEnableObliterate: true,
19
+ };
20
+ const sharedString = new SharedString(dataStoreRuntime, id, SharedStringFactory.Attributes);
21
+ const containerRuntime = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime);
22
+ const services = {
23
+ deltaConnection: dataStoreRuntime.createDeltaConnection(),
24
+ objectStorage: new MockStorage(),
25
+ };
26
+ sharedString.initializeLocal();
27
+ return {
28
+ sharedString,
29
+ containerRuntime,
30
+ services,
31
+ };
32
+ }
33
+ async function loadClient(containerRuntimeFactory, source, id) {
34
+ const { summary } = source.sharedString.getAttachSummary();
35
+ const dataStoreRuntime = new MockFluidDataStoreRuntime();
36
+ dataStoreRuntime.options = {
37
+ intervalStickinessEnabled: true,
38
+ mergeTreeEnableObliterate: true,
39
+ };
40
+ const factory = SharedString.getFactory();
41
+ const containerRuntime = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime);
42
+ const services = {
43
+ deltaConnection: dataStoreRuntime.createDeltaConnection(),
44
+ objectStorage: MockStorage.createFromSummary(summary),
45
+ };
46
+ const sharedString = await factory.load(dataStoreRuntime, id, services, factory.attributes);
47
+ return {
48
+ sharedString,
49
+ containerRuntime,
50
+ };
51
+ }
52
+ function constructClients(containerRuntimeFactory, numClients = 3) {
53
+ return Array.from({ length: numClients }, (_, index) => {
54
+ const { sharedString, containerRuntime, services } = constructClient(containerRuntimeFactory, String.fromCharCode(index + 65));
55
+ sharedString.connect(services);
56
+ return { containerRuntime, sharedString };
57
+ });
58
+ }
59
+ describe("interval rebasing", () => {
60
+ let containerRuntimeFactory;
61
+ let clients;
62
+ useStrictPartialLengthChecks();
63
+ beforeEach(() => {
64
+ containerRuntimeFactory = new MockContainerRuntimeFactoryForReconnection();
65
+ clients = constructClients(containerRuntimeFactory);
66
+ });
67
+ it("does not crash for an interval that lies on segment that has been removed locally", () => {
68
+ clients[0].sharedString.insertText(0, "A");
69
+ clients[1].containerRuntime.connected = false;
70
+ clients[1].sharedString.insertText(0, "01234");
71
+ containerRuntimeFactory.processAllMessages();
72
+ assertConsistent(clients);
73
+ clients[1].containerRuntime.connected = true;
74
+ clients[0].sharedString.insertText(0, "012345678901234");
75
+ clients[0].containerRuntime.connected = false;
76
+ containerRuntimeFactory.processAllMessages();
77
+ assertConsistent(clients);
78
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
79
+ collection_0.add({ start: 12, end: 15, props: { intervalId: "id" } });
80
+ clients[2].sharedString.removeRange(5, 7);
81
+ clients[0].sharedString.removeRange(3, 5);
82
+ containerRuntimeFactory.processAllMessages();
83
+ assertConsistent(clients);
84
+ clients[0].sharedString.insertText(13, "0123");
85
+ clients[0].containerRuntime.connected = true;
86
+ containerRuntimeFactory.processAllMessages();
87
+ assertConsistent(clients);
88
+ });
89
+ it("does not crash when entire string on which interval lies is concurrently removed", () => {
90
+ clients[0].sharedString.insertText(0, "a");
91
+ clients[1].sharedString.insertText(0, "a");
92
+ containerRuntimeFactory.processAllMessages();
93
+ assertConsistent(clients);
94
+ clients[0].containerRuntime.connected = false;
95
+ clients[1].sharedString.removeRange(0, 2);
96
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
97
+ collection_0.add({ start: 0, end: 1, props: { intervalId: "id" } });
98
+ containerRuntimeFactory.processAllMessages();
99
+ assertConsistent(clients);
100
+ clients[0].containerRuntime.connected = true;
101
+ });
102
+ it("does not crash when interval is removed before reconnect when string is concurrently removed", () => {
103
+ clients[0].sharedString.insertText(0, "A");
104
+ clients[1].sharedString.insertText(0, "B");
105
+ containerRuntimeFactory.processAllMessages();
106
+ assertConsistent(clients);
107
+ clients[0].containerRuntime.connected = false;
108
+ clients[1].sharedString.removeRange(0, 2);
109
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
110
+ collection_0.add({ start: 0, end: 1, props: { intervalId: "id" } });
111
+ containerRuntimeFactory.processAllMessages();
112
+ assertConsistent(clients);
113
+ collection_0.removeIntervalById("id");
114
+ clients[0].containerRuntime.connected = true;
115
+ });
116
+ it("does not crash when interval slides off end of string", () => {
117
+ clients[0].sharedString.insertText(0, "012Z45");
118
+ clients[2].sharedString.insertText(0, "X");
119
+ containerRuntimeFactory.processAllMessages();
120
+ assertConsistent(clients);
121
+ clients[1].sharedString.insertText(0, "01234567");
122
+ clients[0].containerRuntime.connected = false;
123
+ containerRuntimeFactory.processAllMessages();
124
+ assertConsistent(clients);
125
+ clients[0].sharedString.insertText(0, "ABCDEFGHIJKLMN");
126
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
127
+ collection_0.add({
128
+ start: 20,
129
+ end: 20,
130
+ props: { intervalId: "0" },
131
+ });
132
+ clients[2].sharedString.removeRange(13, 15);
133
+ containerRuntimeFactory.processAllMessages();
134
+ assertConsistent(clients);
135
+ clients[0].containerRuntime.connected = true;
136
+ containerRuntimeFactory.processAllMessages();
137
+ assertConsistent(clients);
138
+ });
139
+ it("handles basic interval sliding for obliterate", () => {
140
+ // A-(BC)
141
+ clients[0].sharedString.insertText(0, "ABC");
142
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
143
+ collection_0.add({
144
+ start: 0,
145
+ end: 2,
146
+ props: {
147
+ intervalId: "a",
148
+ },
149
+ });
150
+ clients[0].sharedString.obliterateRange(1, 3);
151
+ containerRuntimeFactory.processAllMessages();
152
+ assertConsistent(clients);
153
+ });
154
+ it("reference is -1 for obliterated segment", () => {
155
+ // (L-PC-F)
156
+ clients[1].sharedString.insertText(0, "F");
157
+ clients[0].sharedString.insertText(0, "PC");
158
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
159
+ collection_0.add({
160
+ start: 0,
161
+ end: 1,
162
+ props: {
163
+ intervalId: "a",
164
+ },
165
+ });
166
+ clients[1].sharedString.insertText(0, "L");
167
+ clients[1].sharedString.obliterateRange(0, 2);
168
+ containerRuntimeFactory.processAllMessages();
169
+ assertConsistent(clients);
170
+ });
171
+ it("slides to correct final destination", () => {
172
+ clients[0].sharedString.insertText(0, "A");
173
+ containerRuntimeFactory.processAllMessages();
174
+ assertConsistent(clients);
175
+ clients[2].sharedString.insertText(0, "B");
176
+ clients[2].sharedString.removeRange(0, 2);
177
+ clients[0].sharedString.insertText(0, "C");
178
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
179
+ collection_0.add({
180
+ start: 0,
181
+ end: 1,
182
+ props: { intervalId: "0" },
183
+ });
184
+ containerRuntimeFactory.processAllMessages();
185
+ assertConsistent(clients);
186
+ });
187
+ it("does not slide to invalid position when 0-length interval", () => {
188
+ clients[0].sharedString.insertText(0, "A");
189
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
190
+ // A 0-length interval is required here to reproduce this error. If in
191
+ // the future we wish to stop supporting 0-length intervals, this test
192
+ // can be removed
193
+ collection_0.add({
194
+ start: 0,
195
+ end: 0,
196
+ props: { intervalId: "1" },
197
+ });
198
+ clients[1].sharedString.insertText(0, "BCD");
199
+ clients[1].sharedString.removeRange(0, 1);
200
+ containerRuntimeFactory.processAllMessages();
201
+ assertConsistent(clients);
202
+ clients[2].sharedString.removeRange(1, 3);
203
+ clients[1].sharedString.insertText(1, "E");
204
+ const collection_1 = clients[1].sharedString.getIntervalCollection("comments");
205
+ collection_1.add({
206
+ start: 0,
207
+ end: 2,
208
+ props: {
209
+ intervalId: "2",
210
+ },
211
+ });
212
+ containerRuntimeFactory.processAllMessages();
213
+ assertConsistent(clients);
214
+ assert.equal(clients[0].sharedString.getText(), "CE");
215
+ });
216
+ it("is consistent for full stickiness", () => {
217
+ clients[0].sharedString.insertText(0, "A");
218
+ clients[0].sharedString.insertText(0, "BC");
219
+ containerRuntimeFactory.processAllMessages();
220
+ assertConsistent(clients);
221
+ const collection_1 = clients[1].sharedString.getIntervalCollection("comments");
222
+ const interval1 = collection_1.add({
223
+ start: "start",
224
+ end: "end",
225
+ props: {
226
+ intervalId: "2",
227
+ },
228
+ });
229
+ assert.equal(interval1.stickiness, IntervalStickiness.FULL);
230
+ clients[0].sharedString.removeRange(0, 1);
231
+ clients[1].sharedString.removeRange(0, 3);
232
+ containerRuntimeFactory.processAllMessages();
233
+ assertConsistent(clients);
234
+ });
235
+ it("keeps obliterate segment group the same across multiple reconnects", () => {
236
+ // A-C
237
+ // (A-B-C)
238
+ clients[0].sharedString.insertText(0, "C");
239
+ clients[0].sharedString.insertText(0, "A");
240
+ containerRuntimeFactory.processAllMessages();
241
+ assertConsistent(clients);
242
+ clients[0].sharedString.insertText(1, "B");
243
+ clients[1].sharedString.obliterateRange(0, 2);
244
+ clients[1].containerRuntime.connected = false;
245
+ clients[1].containerRuntime.connected = true;
246
+ clients[1].containerRuntime.connected = false;
247
+ clients[1].containerRuntime.connected = true;
248
+ containerRuntimeFactory.processAllMessages();
249
+ assertConsistent(clients);
250
+ });
251
+ it("doesn't crash for empty pending segment group", () => {
252
+ // A
253
+ // ((A))-[D]
254
+ clients[0].sharedString.insertText(0, "A");
255
+ containerRuntimeFactory.processAllMessages();
256
+ assertConsistent(clients);
257
+ clients[1].sharedString.obliterateRange(0, 1);
258
+ clients[0].sharedString.insertText(1, "D");
259
+ clients[0].sharedString.obliterateRange(0, 1);
260
+ clients[0].sharedString.removeRange(0, 1);
261
+ clients[0].containerRuntime.connected = false;
262
+ containerRuntimeFactory.processAllMessages();
263
+ assertConsistent(clients);
264
+ clients[0].containerRuntime.connected = true;
265
+ assert.equal(clients[0].sharedString.getText(), "");
266
+ containerRuntimeFactory.processAllMessages();
267
+ assertConsistent(clients);
268
+ });
269
+ it("zamboni avoids modifying segments with pending interval changes", () => {
270
+ // C-AB
271
+ // D-C-AB
272
+ // E-HIJ-FG-D-C-AB
273
+ // ^----------^
274
+ clients[2].sharedString.insertText(0, "AB");
275
+ clients[0].sharedString.insertText(0, "C");
276
+ containerRuntimeFactory.processAllMessages();
277
+ assertConsistent(clients);
278
+ clients[1].containerRuntime.connected = false;
279
+ clients[2].sharedString.insertText(0, "D");
280
+ containerRuntimeFactory.processAllMessages();
281
+ assertConsistent(clients);
282
+ clients[2].sharedString.insertText(0, "E");
283
+ clients[1].sharedString.insertText(0, "FG");
284
+ clients[1].sharedString.insertText(0, "HIJ");
285
+ clients[0].containerRuntime.connected = false;
286
+ const collection_0 = clients[1].sharedString.getIntervalCollection("comments");
287
+ collection_0.add({ start: 0, end: 7 });
288
+ containerRuntimeFactory.processAllMessages();
289
+ assertConsistent(clients);
290
+ clients[1].containerRuntime.connected = true;
291
+ });
292
+ it("zamboni avoids modifying segments with pending interval changes through multiple reconnects", async () => {
293
+ // Note: the specifics of the attach flow shouldn't be necessary here to reproduce this issue.
294
+ // All that's necessary is that the "R" segment is zamboni'd.
295
+ // However, due to zamboni's fragility, some care needs to be taken for that to happen.
296
+ // See AB#7048 for more details.
297
+ const A = constructClient(containerRuntimeFactory, "A");
298
+ A.sharedString.insertText(0, "Rr");
299
+ A.sharedString.connect(A.services);
300
+ const B = await loadClient(containerRuntimeFactory, A, "B");
301
+ B.sharedString.removeRange(0, 1);
302
+ const collection = A.sharedString.getIntervalCollection("comments");
303
+ collection.add({ start: { pos: 1, side: Side.After }, end: { pos: 0, side: Side.Before } });
304
+ A.containerRuntime.connected = false;
305
+ containerRuntimeFactory.processAllMessages();
306
+ B.sharedString.insertText(0, "8");
307
+ A.containerRuntime.connected = true;
308
+ A.containerRuntime.connected = false;
309
+ B.sharedString.insertText(0, "J");
310
+ containerRuntimeFactory.processAllMessages();
311
+ A.containerRuntime.connected = true;
312
+ containerRuntimeFactory.processAllMessages();
313
+ assertConsistent([A, B]);
314
+ });
315
+ // Reproduction of seed 70. Appears to be some problem with normalization of segments interacting
316
+ // with sliding logic on reconnect. The ordering of the 22222 and 11 segments is not consistent
317
+ // across clients even when in the collab window, and the local reference gets put on this segment.
318
+ // So clients[0] disagrees with the others about where the reference slides.
319
+ it.skip("AB#6552", () => {
320
+ // Note: all 3 clients submit edits. When debugging this test, it might be helpful to
321
+ // add a 4th client that doesn't submit any edits. E.g.:
322
+ // clients = constructClients(containerRuntimeFactory, 4);
323
+ clients[0].sharedString.insertText(0, "000");
324
+ containerRuntimeFactory.processAllMessages();
325
+ clients[0].containerRuntime.connected = false;
326
+ clients[1].containerRuntime.connected = false;
327
+ clients[1].sharedString.insertText(0, "11");
328
+ clients[0].sharedString.insertText(1, "22222");
329
+ clients[0].sharedString
330
+ .getIntervalCollection("test collection")
331
+ .add({ start: { pos: 1, side: Side.After }, end: { pos: 1, side: Side.After } });
332
+ clients[0].sharedString.removeRange(0, 6);
333
+ clients[2].sharedString.removeRange(0, 2);
334
+ containerRuntimeFactory.processAllMessages();
335
+ clients[0].sharedString.insertText(1, "3");
336
+ clients[1].containerRuntime.connected = true;
337
+ clients[0].containerRuntime.connected = true;
338
+ containerRuntimeFactory.processAllMessages();
339
+ assertConsistent(clients);
340
+ });
341
+ it("doesn't create empty segment group when obliterated segment was obliterated by other client during reconnect", () => {
342
+ // A
343
+ // ((A))-[D]
344
+ clients[0].sharedString.insertText(0, "A");
345
+ containerRuntimeFactory.processAllMessages();
346
+ assertConsistent(clients);
347
+ clients[1].sharedString.obliterateRange(0, 1);
348
+ clients[0].sharedString.insertText(1, "D");
349
+ clients[0].sharedString.obliterateRange(0, 1);
350
+ clients[0].sharedString.removeRange(0, 1);
351
+ clients[0].containerRuntime.connected = false;
352
+ containerRuntimeFactory.processAllMessages();
353
+ assertConsistent(clients);
354
+ clients[0].containerRuntime.connected = true;
355
+ clients[0].containerRuntime.connected = false;
356
+ clients[0].containerRuntime.connected = true;
357
+ assert.equal(clients[0].sharedString.getText(), "");
358
+ containerRuntimeFactory.processAllMessages();
359
+ assertConsistent(clients);
360
+ });
361
+ // todo: a failing obliterate reconnect test. when rebasing the op,
362
+ // the character "C" has been concurrently obliterated, so the reconnect
363
+ // position of "B" is computed to be 0, rather than 1
364
+ //
365
+ // at the time of writing, i'm not sure of a good solution. either we could
366
+ // change calculation of reconnection position in some way or we could not
367
+ // concurrently obliterate "C" in this context.
368
+ //
369
+ // in both cases, it's not clear to me how we detect when we're reconnecting
370
+ //
371
+ // ADO#3714
372
+ it.skip("...", () => {
373
+ // AB
374
+ // A-C-B
375
+ clients[0].sharedString.insertText(0, "AB");
376
+ containerRuntimeFactory.processAllMessages();
377
+ assertConsistent(clients);
378
+ clients[0].sharedString.insertText(1, "C");
379
+ clients[1].containerRuntime.connected = false;
380
+ clients[1].sharedString.obliterateRange(0, 2);
381
+ clients[1].containerRuntime.connected = true;
382
+ clients[1].containerRuntime.connected = false;
383
+ containerRuntimeFactory.processAllMessages();
384
+ assertConsistent(clients);
385
+ clients[1].containerRuntime.connected = true;
386
+ containerRuntimeFactory.processAllMessages();
387
+ assertConsistent(clients);
388
+ });
389
+ // todo: ADO#3714 Failing obliterate reconnect test
390
+ it.skip("...", () => {
391
+ clients[0].sharedString.insertText(0, "AB");
392
+ clients[1].sharedString.insertText(0, "CD");
393
+ clients[1].sharedString.insertText(1, "E");
394
+ clients[0].sharedString.obliterateRange(0, 1);
395
+ clients[0].sharedString.insertText(0, "FGHIJK");
396
+ containerRuntimeFactory.processAllMessages();
397
+ assertConsistent(clients);
398
+ clients[0].sharedString.insertText(4, "L");
399
+ clients[2].sharedString.obliterateRange(3, 5);
400
+ clients[0].containerRuntime.connected = false;
401
+ clients[0].sharedString.obliterateRange(1, 2);
402
+ clients[0].sharedString.insertText(7, "M");
403
+ containerRuntimeFactory.processAllMessages();
404
+ assertConsistent(clients);
405
+ clients[0].containerRuntime.connected = true;
406
+ containerRuntimeFactory.processAllMessages();
407
+ assertConsistent(clients);
408
+ });
409
+ it("slides two refs on same segment to different segments", () => {
410
+ clients[0].sharedString.insertText(0, "AB");
411
+ clients[0].sharedString.insertText(0, "C");
412
+ const collection_1 = clients[0].sharedString.getIntervalCollection("comments");
413
+ const interval1 = collection_1.add({
414
+ start: { pos: 0, side: Side.After },
415
+ end: "end",
416
+ props: {
417
+ intervalId: "1",
418
+ },
419
+ });
420
+ assert.equal(interval1.stickiness, IntervalStickiness.FULL);
421
+ containerRuntimeFactory.processAllMessages();
422
+ assertConsistent(clients);
423
+ clients[2].sharedString.removeRange(1, 2);
424
+ const collection_2 = clients[1].sharedString.getIntervalCollection("comments");
425
+ const interval2 = collection_2.add({
426
+ start: "start",
427
+ end: { pos: 2, side: Side.Before },
428
+ props: {
429
+ intervalId: "2",
430
+ },
431
+ });
432
+ assert.equal(interval2.stickiness, IntervalStickiness.FULL);
433
+ containerRuntimeFactory.processAllMessages();
434
+ assertConsistent(clients);
435
+ });
436
+ it("maintains sliding preference on references after ack", () => {
437
+ clients[1].sharedString.insertText(0, "ABC");
438
+ containerRuntimeFactory.processAllMessages();
439
+ assertConsistent(clients);
440
+ clients[0].sharedString.removeRange(0, 1);
441
+ clients[0].sharedString.insertText(0, "D");
442
+ const collection_1 = clients[1].sharedString.getIntervalCollection("comments");
443
+ collection_1.add({
444
+ start: { pos: 0, side: Side.After },
445
+ end: 1,
446
+ props: {
447
+ intervalId: "1",
448
+ },
449
+ });
450
+ clients[2].sharedString.removeRange(1, 2);
451
+ containerRuntimeFactory.processAllMessages();
452
+ assertConsistent(clients);
453
+ });
454
+ it("maintains sliding preference on references after reconnect with special endpoint segment", () => {
455
+ clients[0].sharedString.insertText(0, "D");
456
+ clients[0].containerRuntime.connected = false;
457
+ const collection_1 = clients[0].sharedString.getIntervalCollection("comments");
458
+ const interval = collection_1.add({
459
+ start: "start",
460
+ end: 0,
461
+ props: {
462
+ intervalId: "1",
463
+ },
464
+ });
465
+ assert.equal(interval.stickiness, IntervalStickiness.FULL);
466
+ clients[0].containerRuntime.connected = true;
467
+ containerRuntimeFactory.processAllMessages();
468
+ assertConsistent(clients);
469
+ });
470
+ it("maintains sliding preference on references after reconnect", () => {
471
+ clients[0].sharedString.insertText(0, "D");
472
+ clients[0].containerRuntime.connected = false;
473
+ const collection_1 = clients[0].sharedString.getIntervalCollection("comments");
474
+ const interval = collection_1.add({
475
+ start: { pos: 0, side: Side.After },
476
+ end: 0,
477
+ props: {
478
+ intervalId: "1",
479
+ },
480
+ });
481
+ assert.equal(interval.stickiness, IntervalStickiness.FULL);
482
+ clients[0].containerRuntime.connected = true;
483
+ containerRuntimeFactory.processAllMessages();
484
+ assertConsistent(clients);
485
+ });
486
+ // todo: potentially related to AB#7050
487
+ //
488
+ // this is a reduced fuzz test from the suite
489
+ // `SharedString with rebasing and reconnect`
490
+ it.skip("...", async () => {
491
+ const A = constructClient(containerRuntimeFactory, "A");
492
+ A.sharedString.insertText(0, "ABCDEF");
493
+ A.sharedString.insertText(0, "GHIJ");
494
+ A.sharedString.insertText(0, "KLMNO");
495
+ A.sharedString.insertText(0, "PQRST");
496
+ // attach
497
+ A.sharedString.connect(A.services);
498
+ const B = await loadClient(containerRuntimeFactory, A, "B");
499
+ A.sharedString.insertText(0, "UVWXYZ");
500
+ containerRuntimeFactory.processAllMessages();
501
+ assertConsistent([A, B]);
502
+ B.sharedString.insertText(26, "1");
503
+ A.sharedString.removeRange(0, 1);
504
+ B.containerRuntime.connected = false;
505
+ containerRuntimeFactory.processAllMessages();
506
+ assertConsistent([A, B]);
507
+ B.containerRuntime.connected = true;
508
+ containerRuntimeFactory.processAllMessages();
509
+ assertConsistent([A, B]);
510
+ });
511
+ it("slides to correct segment when inserting segment while disconnected after changing interval", () => {
512
+ // B-A
513
+ // ^
514
+ clients[0].sharedString.insertText(0, "A");
515
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
516
+ collection_0.add({ start: 0, end: 0, props: { intervalId: "0" } });
517
+ collection_0.change("0", { start: 0, end: 0 });
518
+ clients[0].containerRuntime.connected = false;
519
+ clients[0].sharedString.insertText(0, "B");
520
+ clients[0].containerRuntime.connected = true;
521
+ containerRuntimeFactory.processAllMessages();
522
+ assertConsistent(clients);
523
+ assert.equal(clients[0].sharedString.getText(), "BA");
524
+ assertSequenceIntervals(clients[0].sharedString, clients[0].sharedString.getIntervalCollection("comments"), [{ start: 1, end: 1 }]);
525
+ });
526
+ it("changing interval to concurrently deleted segment detaches interval", () => {
527
+ // B-A
528
+ // ^
529
+ // (B)-A
530
+ // ^
531
+ // (B)-(A)-C
532
+ // ^
533
+ clients[0].sharedString.insertText(0, "A");
534
+ clients[2].sharedString.insertText(0, "B");
535
+ const collection_0 = clients[2].sharedString.getIntervalCollection("comments");
536
+ collection_0.add({ start: 0, end: 0, props: { intervalId: "0" } });
537
+ containerRuntimeFactory.processAllMessages();
538
+ assertConsistent(clients);
539
+ clients[1].sharedString.removeRange(0, 1);
540
+ clients[0].containerRuntime.connected = false;
541
+ containerRuntimeFactory.processAllMessages();
542
+ assertConsistent(clients);
543
+ clients[1].sharedString.removeRange(0, 1);
544
+ const collection_1 = clients[0].sharedString.getIntervalCollection("comments");
545
+ collection_1.change("0", { start: 0, end: 0 });
546
+ clients[2].sharedString.insertText(0, "C");
547
+ containerRuntimeFactory.processAllMessages();
548
+ assertConsistent(clients);
549
+ clients[0].containerRuntime.connected = true;
550
+ containerRuntimeFactory.processAllMessages();
551
+ assertConsistent(clients);
552
+ assert.equal(clients[0].sharedString.getText(), "C");
553
+ assertSequenceIntervals(clients[0].sharedString, clients[0].sharedString.getIntervalCollection("comments"), [{ start: 0, end: 0 }]);
554
+ });
555
+ it("changing interval endpoint while disconnected to segment also inserted while disconnected", () => {
556
+ // AC
557
+ // A-B-C
558
+ clients[0].sharedString.insertText(0, "AC");
559
+ containerRuntimeFactory.processAllMessages();
560
+ assertConsistent(clients);
561
+ const collection_0 = clients[0].sharedString.getIntervalCollection("comments");
562
+ collection_0.add({ start: 0, end: 0, props: { intervalId: "0" } });
563
+ clients[0].containerRuntime.connected = false;
564
+ clients[0].sharedString.insertText(1, "B");
565
+ collection_0.change("0", { start: 1, end: 1 });
566
+ clients[0].containerRuntime.connected = true;
567
+ containerRuntimeFactory.processAllMessages();
568
+ assertConsistent(clients);
569
+ assert.equal(clients[0].sharedString.getText(), "ABC");
570
+ assertSequenceIntervals(clients[0].sharedString, clients[0].sharedString.getIntervalCollection("comments"), [{ start: 1, end: 1 }]);
571
+ });
572
+ it("delete and insert text into range containing interval while disconnected", async () => {
573
+ // 012
574
+ // (0)-x-12
575
+ clients[0].containerRuntime.connected = false;
576
+ const intervals = clients[0].sharedString.getIntervalCollection("comments");
577
+ clients[0].sharedString.insertText(0, "012");
578
+ intervals.add({ start: 0, end: 2, props: { intervalId: "0" } });
579
+ assertSequenceIntervals(clients[0].sharedString, intervals, [{ start: 0, end: 2 }]);
580
+ clients[0].sharedString.insertText(1, "x");
581
+ clients[0].sharedString.removeRange(0, 1);
582
+ clients[0].containerRuntime.connected = true;
583
+ containerRuntimeFactory.processAllMessages();
584
+ assertConsistent(clients);
585
+ assert.equal(clients[0].sharedString.getText(), "x12");
586
+ assertSequenceIntervals(clients[0].sharedString, intervals, [{ start: 0, end: 2 }]);
587
+ });
588
+ });
589
+ //# sourceMappingURL=intervalRebasing.spec.js.map