@fluidframework/sequence 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.224419

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 (349) hide show
  1. package/.eslintrc.js +9 -11
  2. package/.mocharc.js +12 -0
  3. package/CHANGELOG.md +449 -0
  4. package/README.md +364 -183
  5. package/api-extractor-lint.json +4 -0
  6. package/api-extractor.json +2 -2
  7. package/api-report/sequence.api.md +741 -0
  8. package/dist/{defaultMap.js → defaultMap.cjs} +29 -22
  9. package/dist/defaultMap.cjs.map +1 -0
  10. package/dist/defaultMap.d.ts +7 -6
  11. package/dist/defaultMap.d.ts.map +1 -1
  12. package/dist/defaultMapInterfaces.cjs +7 -0
  13. package/dist/defaultMapInterfaces.cjs.map +1 -0
  14. package/dist/defaultMapInterfaces.d.ts +44 -12
  15. package/dist/defaultMapInterfaces.d.ts.map +1 -1
  16. package/dist/index.cjs +60 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.ts +14 -12
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/intervalCollection.cjs +1159 -0
  21. package/dist/intervalCollection.cjs.map +1 -0
  22. package/dist/intervalCollection.d.ts +461 -162
  23. package/dist/intervalCollection.d.ts.map +1 -1
  24. package/dist/intervalIndex/endpointInRangeIndex.cjs +66 -0
  25. package/dist/intervalIndex/endpointInRangeIndex.cjs.map +1 -0
  26. package/dist/intervalIndex/endpointInRangeIndex.d.ts +34 -0
  27. package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -0
  28. package/dist/intervalIndex/endpointIndex.cjs +47 -0
  29. package/dist/intervalIndex/endpointIndex.cjs.map +1 -0
  30. package/dist/intervalIndex/endpointIndex.d.ts +38 -0
  31. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -0
  32. package/dist/intervalIndex/idIntervalIndex.cjs +44 -0
  33. package/dist/intervalIndex/idIntervalIndex.cjs.map +1 -0
  34. package/dist/intervalIndex/idIntervalIndex.d.ts +18 -0
  35. package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -0
  36. package/dist/intervalIndex/index.cjs +24 -0
  37. package/dist/intervalIndex/index.cjs.map +1 -0
  38. package/dist/intervalIndex/index.d.ts +13 -0
  39. package/dist/intervalIndex/index.d.ts.map +1 -0
  40. package/dist/{defaultMapInterfaces.js → intervalIndex/intervalIndex.cjs} +1 -1
  41. package/dist/intervalIndex/intervalIndex.cjs.map +1 -0
  42. package/dist/intervalIndex/intervalIndex.d.ts +30 -0
  43. package/dist/intervalIndex/intervalIndex.d.ts.map +1 -0
  44. package/dist/intervalIndex/intervalIndexUtils.cjs +22 -0
  45. package/dist/intervalIndex/intervalIndexUtils.cjs.map +1 -0
  46. package/dist/intervalIndex/intervalIndexUtils.d.ts +17 -0
  47. package/dist/intervalIndex/intervalIndexUtils.d.ts.map +1 -0
  48. package/dist/intervalIndex/overlappingIntervalsIndex.cjs +116 -0
  49. package/dist/intervalIndex/overlappingIntervalsIndex.cjs.map +1 -0
  50. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +44 -0
  51. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
  52. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.cjs +41 -0
  53. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.cjs.map +1 -0
  54. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +11 -0
  55. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
  56. package/dist/intervalIndex/sequenceIntervalIndexes.cjs +7 -0
  57. package/dist/intervalIndex/sequenceIntervalIndexes.cjs.map +1 -0
  58. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +35 -0
  59. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
  60. package/dist/intervalIndex/startpointInRangeIndex.cjs +66 -0
  61. package/dist/intervalIndex/startpointInRangeIndex.cjs.map +1 -0
  62. package/dist/intervalIndex/startpointInRangeIndex.d.ts +34 -0
  63. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -0
  64. package/dist/intervalTree.cjs +80 -0
  65. package/dist/intervalTree.cjs.map +1 -0
  66. package/dist/intervalTree.d.ts +24 -0
  67. package/dist/intervalTree.d.ts.map +1 -0
  68. package/dist/intervals/index.cjs +23 -0
  69. package/dist/intervals/index.cjs.map +1 -0
  70. package/dist/intervals/index.d.ts +8 -0
  71. package/dist/intervals/index.d.ts.map +1 -0
  72. package/dist/intervals/interval.cjs +181 -0
  73. package/dist/intervals/interval.cjs.map +1 -0
  74. package/dist/intervals/interval.d.ts +84 -0
  75. package/dist/intervals/interval.d.ts.map +1 -0
  76. package/dist/intervals/intervalUtils.cjs +83 -0
  77. package/dist/intervals/intervalUtils.cjs.map +1 -0
  78. package/dist/intervals/intervalUtils.d.ts +230 -0
  79. package/dist/intervals/intervalUtils.d.ts.map +1 -0
  80. package/dist/intervals/sequenceInterval.cjs +378 -0
  81. package/dist/intervals/sequenceInterval.cjs.map +1 -0
  82. package/dist/intervals/sequenceInterval.d.ts +137 -0
  83. package/dist/intervals/sequenceInterval.d.ts.map +1 -0
  84. package/dist/{localValues.js → localValues.cjs} +1 -1
  85. package/dist/localValues.cjs.map +1 -0
  86. package/dist/localValues.d.ts +2 -1
  87. package/dist/localValues.d.ts.map +1 -1
  88. package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
  89. package/dist/packageVersion.cjs.map +1 -0
  90. package/dist/packageVersion.d.ts +1 -1
  91. package/dist/packageVersion.d.ts.map +1 -1
  92. package/dist/revertibles.cjs +425 -0
  93. package/dist/revertibles.cjs.map +1 -0
  94. package/dist/revertibles.d.ts +86 -0
  95. package/dist/revertibles.d.ts.map +1 -0
  96. package/dist/sequence-alpha.d.ts +1315 -0
  97. package/dist/sequence-beta.d.ts +244 -0
  98. package/dist/sequence-public.d.ts +244 -0
  99. package/dist/sequence-untrimmed.d.ts +1803 -0
  100. package/dist/{sequence.js → sequence.cjs} +226 -156
  101. package/dist/sequence.cjs.map +1 -0
  102. package/dist/sequence.d.ts +125 -48
  103. package/dist/sequence.d.ts.map +1 -1
  104. package/dist/{sequenceDeltaEvent.js → sequenceDeltaEvent.cjs} +18 -8
  105. package/dist/sequenceDeltaEvent.cjs.map +1 -0
  106. package/dist/sequenceDeltaEvent.d.ts +24 -7
  107. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  108. package/dist/sequenceFactory.cjs +55 -0
  109. package/dist/sequenceFactory.cjs.map +1 -0
  110. package/dist/sequenceFactory.d.ts +3 -89
  111. package/dist/sequenceFactory.d.ts.map +1 -1
  112. package/dist/{sharedIntervalCollection.js → sharedIntervalCollection.cjs} +17 -22
  113. package/dist/sharedIntervalCollection.cjs.map +1 -0
  114. package/dist/sharedIntervalCollection.d.ts +12 -12
  115. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  116. package/dist/{sharedSequence.js → sharedSequence.cjs} +29 -22
  117. package/dist/sharedSequence.cjs.map +1 -0
  118. package/dist/sharedSequence.d.ts +14 -2
  119. package/dist/sharedSequence.d.ts.map +1 -1
  120. package/dist/sharedString.cjs +286 -0
  121. package/dist/sharedString.cjs.map +1 -0
  122. package/dist/sharedString.d.ts +58 -22
  123. package/dist/sharedString.d.ts.map +1 -1
  124. package/dist/tsdoc-metadata.json +11 -0
  125. package/lib/{defaultMap.d.ts → defaultMap.d.mts} +7 -6
  126. package/lib/defaultMap.d.mts.map +1 -0
  127. package/lib/{defaultMap.js → defaultMap.mjs} +28 -21
  128. package/lib/defaultMap.mjs.map +1 -0
  129. package/lib/{defaultMapInterfaces.d.ts → defaultMapInterfaces.d.mts} +44 -12
  130. package/lib/defaultMapInterfaces.d.mts.map +1 -0
  131. package/lib/defaultMapInterfaces.mjs +6 -0
  132. package/lib/defaultMapInterfaces.mjs.map +1 -0
  133. package/lib/index.d.mts +17 -0
  134. package/lib/index.d.mts.map +1 -0
  135. package/lib/index.mjs +16 -0
  136. package/lib/index.mjs.map +1 -0
  137. package/lib/intervalCollection.d.mts +569 -0
  138. package/lib/intervalCollection.d.mts.map +1 -0
  139. package/lib/intervalCollection.mjs +1144 -0
  140. package/lib/intervalCollection.mjs.map +1 -0
  141. package/lib/intervalIndex/endpointInRangeIndex.d.mts +34 -0
  142. package/lib/intervalIndex/endpointInRangeIndex.d.mts.map +1 -0
  143. package/lib/intervalIndex/endpointInRangeIndex.mjs +61 -0
  144. package/lib/intervalIndex/endpointInRangeIndex.mjs.map +1 -0
  145. package/lib/intervalIndex/endpointIndex.d.mts +38 -0
  146. package/lib/intervalIndex/endpointIndex.d.mts.map +1 -0
  147. package/lib/intervalIndex/endpointIndex.mjs +42 -0
  148. package/lib/intervalIndex/endpointIndex.mjs.map +1 -0
  149. package/lib/intervalIndex/idIntervalIndex.d.mts +18 -0
  150. package/lib/intervalIndex/idIntervalIndex.d.mts.map +1 -0
  151. package/lib/intervalIndex/idIntervalIndex.mjs +40 -0
  152. package/lib/intervalIndex/idIntervalIndex.mjs.map +1 -0
  153. package/lib/intervalIndex/index.d.mts +13 -0
  154. package/lib/intervalIndex/index.d.mts.map +1 -0
  155. package/lib/intervalIndex/index.mjs +11 -0
  156. package/lib/intervalIndex/index.mjs.map +1 -0
  157. package/lib/intervalIndex/intervalIndex.d.mts +30 -0
  158. package/lib/intervalIndex/intervalIndex.d.mts.map +1 -0
  159. package/lib/{defaultMapInterfaces.js → intervalIndex/intervalIndex.mjs} +1 -1
  160. package/lib/intervalIndex/intervalIndex.mjs.map +1 -0
  161. package/lib/intervalIndex/intervalIndexUtils.d.mts +17 -0
  162. package/lib/intervalIndex/intervalIndexUtils.d.mts.map +1 -0
  163. package/lib/intervalIndex/intervalIndexUtils.mjs +18 -0
  164. package/lib/intervalIndex/intervalIndexUtils.mjs.map +1 -0
  165. package/lib/intervalIndex/overlappingIntervalsIndex.d.mts +44 -0
  166. package/lib/intervalIndex/overlappingIntervalsIndex.d.mts.map +1 -0
  167. package/lib/intervalIndex/overlappingIntervalsIndex.mjs +111 -0
  168. package/lib/intervalIndex/overlappingIntervalsIndex.mjs.map +1 -0
  169. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts +11 -0
  170. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts.map +1 -0
  171. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs +37 -0
  172. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs.map +1 -0
  173. package/lib/intervalIndex/sequenceIntervalIndexes.d.mts +35 -0
  174. package/lib/intervalIndex/sequenceIntervalIndexes.d.mts.map +1 -0
  175. package/lib/intervalIndex/sequenceIntervalIndexes.mjs +6 -0
  176. package/lib/intervalIndex/sequenceIntervalIndexes.mjs.map +1 -0
  177. package/lib/intervalIndex/startpointInRangeIndex.d.mts +34 -0
  178. package/lib/intervalIndex/startpointInRangeIndex.d.mts.map +1 -0
  179. package/lib/intervalIndex/startpointInRangeIndex.mjs +61 -0
  180. package/lib/intervalIndex/startpointInRangeIndex.mjs.map +1 -0
  181. package/lib/intervalTree.d.mts +24 -0
  182. package/lib/intervalTree.d.mts.map +1 -0
  183. package/lib/intervalTree.mjs +76 -0
  184. package/lib/intervalTree.mjs.map +1 -0
  185. package/lib/intervals/index.d.mts +8 -0
  186. package/lib/intervals/index.d.mts.map +1 -0
  187. package/lib/intervals/index.mjs +8 -0
  188. package/lib/intervals/index.mjs.map +1 -0
  189. package/lib/intervals/interval.d.mts +84 -0
  190. package/lib/intervals/interval.d.mts.map +1 -0
  191. package/lib/intervals/interval.mjs +176 -0
  192. package/lib/intervals/interval.mjs.map +1 -0
  193. package/lib/intervals/intervalUtils.d.mts +230 -0
  194. package/lib/intervals/intervalUtils.d.mts.map +1 -0
  195. package/lib/intervals/intervalUtils.mjs +77 -0
  196. package/lib/intervals/intervalUtils.mjs.map +1 -0
  197. package/lib/intervals/sequenceInterval.d.mts +137 -0
  198. package/lib/intervals/sequenceInterval.d.mts.map +1 -0
  199. package/lib/intervals/sequenceInterval.mjs +370 -0
  200. package/lib/intervals/sequenceInterval.mjs.map +1 -0
  201. package/lib/{localValues.d.ts → localValues.d.mts} +3 -2
  202. package/lib/localValues.d.mts.map +1 -0
  203. package/lib/{localValues.js → localValues.mjs} +2 -2
  204. package/lib/localValues.mjs.map +1 -0
  205. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
  206. package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
  207. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  208. package/lib/packageVersion.mjs.map +1 -0
  209. package/lib/revertibles.d.mts +86 -0
  210. package/lib/revertibles.d.mts.map +1 -0
  211. package/lib/revertibles.mjs +416 -0
  212. package/lib/revertibles.mjs.map +1 -0
  213. package/lib/sequence-alpha.d.mts +1315 -0
  214. package/lib/sequence-beta.d.mts +244 -0
  215. package/lib/sequence-public.d.mts +244 -0
  216. package/lib/sequence-untrimmed.d.mts +1803 -0
  217. package/lib/{sequence.d.ts → sequence.d.mts} +127 -50
  218. package/lib/sequence.d.mts.map +1 -0
  219. package/lib/{sequence.js → sequence.mjs} +225 -152
  220. package/lib/sequence.mjs.map +1 -0
  221. package/lib/{sequenceDeltaEvent.d.ts → sequenceDeltaEvent.d.mts} +24 -7
  222. package/lib/sequenceDeltaEvent.d.mts.map +1 -0
  223. package/lib/{sequenceDeltaEvent.js → sequenceDeltaEvent.mjs} +20 -8
  224. package/lib/sequenceDeltaEvent.mjs.map +1 -0
  225. package/lib/sequenceFactory.d.mts +22 -0
  226. package/lib/sequenceFactory.d.mts.map +1 -0
  227. package/lib/sequenceFactory.mjs +51 -0
  228. package/lib/sequenceFactory.mjs.map +1 -0
  229. package/lib/{sharedIntervalCollection.d.ts → sharedIntervalCollection.d.mts} +12 -12
  230. package/lib/sharedIntervalCollection.d.mts.map +1 -0
  231. package/lib/{sharedIntervalCollection.js → sharedIntervalCollection.mjs} +16 -21
  232. package/lib/sharedIntervalCollection.mjs.map +1 -0
  233. package/lib/{sharedSequence.d.ts → sharedSequence.d.mts} +15 -3
  234. package/lib/sharedSequence.d.mts.map +1 -0
  235. package/lib/{sharedSequence.js → sharedSequence.mjs} +30 -23
  236. package/lib/sharedSequence.mjs.map +1 -0
  237. package/lib/{sharedString.d.ts → sharedString.d.mts} +60 -24
  238. package/lib/sharedString.d.mts.map +1 -0
  239. package/lib/sharedString.mjs +281 -0
  240. package/lib/sharedString.mjs.map +1 -0
  241. package/package.json +146 -75
  242. package/prettier.config.cjs +8 -0
  243. package/sequence.test-files.tar +0 -0
  244. package/src/defaultMap.ts +417 -403
  245. package/src/defaultMapInterfaces.ts +157 -117
  246. package/src/index.ts +86 -26
  247. package/src/intervalCollection.ts +2043 -1563
  248. package/src/intervalIndex/endpointInRangeIndex.ts +116 -0
  249. package/src/intervalIndex/endpointIndex.ts +91 -0
  250. package/src/intervalIndex/idIntervalIndex.ts +64 -0
  251. package/src/intervalIndex/index.ts +25 -0
  252. package/src/intervalIndex/intervalIndex.ts +32 -0
  253. package/src/intervalIndex/intervalIndexUtils.ts +27 -0
  254. package/src/intervalIndex/overlappingIntervalsIndex.ts +187 -0
  255. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +80 -0
  256. package/src/intervalIndex/sequenceIntervalIndexes.ts +34 -0
  257. package/src/intervalIndex/startpointInRangeIndex.ts +114 -0
  258. package/src/intervalTree.ts +98 -0
  259. package/src/intervals/index.ts +25 -0
  260. package/src/intervals/interval.ts +238 -0
  261. package/src/intervals/intervalUtils.ts +288 -0
  262. package/src/intervals/sequenceInterval.ts +616 -0
  263. package/src/localValues.ts +68 -73
  264. package/src/packageVersion.ts +1 -1
  265. package/src/revertibles.ts +693 -0
  266. package/src/sequence.ts +845 -690
  267. package/src/sequenceDeltaEvent.ts +164 -131
  268. package/src/sequenceFactory.ts +58 -214
  269. package/src/sharedIntervalCollection.ts +161 -152
  270. package/src/sharedSequence.ts +181 -167
  271. package/src/sharedString.ts +390 -234
  272. package/tsc-multi.test.json +10 -0
  273. package/tsconfig.json +11 -13
  274. package/.editorconfig +0 -7
  275. package/.vscode/launch.json +0 -15
  276. package/dist/defaultMap.js.map +0 -1
  277. package/dist/defaultMapInterfaces.js.map +0 -1
  278. package/dist/index.js +0 -44
  279. package/dist/index.js.map +0 -1
  280. package/dist/intervalCollection.js +0 -1250
  281. package/dist/intervalCollection.js.map +0 -1
  282. package/dist/localValues.js.map +0 -1
  283. package/dist/packageVersion.js.map +0 -1
  284. package/dist/sequence.js.map +0 -1
  285. package/dist/sequenceDeltaEvent.js.map +0 -1
  286. package/dist/sequenceFactory.js +0 -192
  287. package/dist/sequenceFactory.js.map +0 -1
  288. package/dist/sharedIntervalCollection.js.map +0 -1
  289. package/dist/sharedNumberSequence.d.ts +0 -50
  290. package/dist/sharedNumberSequence.d.ts.map +0 -1
  291. package/dist/sharedNumberSequence.js +0 -61
  292. package/dist/sharedNumberSequence.js.map +0 -1
  293. package/dist/sharedObjectSequence.d.ts +0 -50
  294. package/dist/sharedObjectSequence.d.ts.map +0 -1
  295. package/dist/sharedObjectSequence.js +0 -61
  296. package/dist/sharedObjectSequence.js.map +0 -1
  297. package/dist/sharedSequence.js.map +0 -1
  298. package/dist/sharedString.js +0 -187
  299. package/dist/sharedString.js.map +0 -1
  300. package/dist/sparsematrix.d.ts +0 -139
  301. package/dist/sparsematrix.d.ts.map +0 -1
  302. package/dist/sparsematrix.js +0 -332
  303. package/dist/sparsematrix.js.map +0 -1
  304. package/lib/defaultMap.d.ts.map +0 -1
  305. package/lib/defaultMap.js.map +0 -1
  306. package/lib/defaultMapInterfaces.d.ts.map +0 -1
  307. package/lib/defaultMapInterfaces.js.map +0 -1
  308. package/lib/index.d.ts +0 -27
  309. package/lib/index.d.ts.map +0 -1
  310. package/lib/index.js +0 -26
  311. package/lib/index.js.map +0 -1
  312. package/lib/intervalCollection.d.ts +0 -270
  313. package/lib/intervalCollection.d.ts.map +0 -1
  314. package/lib/intervalCollection.js +0 -1238
  315. package/lib/intervalCollection.js.map +0 -1
  316. package/lib/localValues.d.ts.map +0 -1
  317. package/lib/localValues.js.map +0 -1
  318. package/lib/packageVersion.js.map +0 -1
  319. package/lib/sequence.d.ts.map +0 -1
  320. package/lib/sequence.js.map +0 -1
  321. package/lib/sequenceDeltaEvent.d.ts.map +0 -1
  322. package/lib/sequenceDeltaEvent.js.map +0 -1
  323. package/lib/sequenceFactory.d.ts +0 -108
  324. package/lib/sequenceFactory.d.ts.map +0 -1
  325. package/lib/sequenceFactory.js +0 -186
  326. package/lib/sequenceFactory.js.map +0 -1
  327. package/lib/sharedIntervalCollection.d.ts.map +0 -1
  328. package/lib/sharedIntervalCollection.js.map +0 -1
  329. package/lib/sharedNumberSequence.d.ts +0 -50
  330. package/lib/sharedNumberSequence.d.ts.map +0 -1
  331. package/lib/sharedNumberSequence.js +0 -57
  332. package/lib/sharedNumberSequence.js.map +0 -1
  333. package/lib/sharedObjectSequence.d.ts +0 -50
  334. package/lib/sharedObjectSequence.d.ts.map +0 -1
  335. package/lib/sharedObjectSequence.js +0 -57
  336. package/lib/sharedObjectSequence.js.map +0 -1
  337. package/lib/sharedSequence.d.ts.map +0 -1
  338. package/lib/sharedSequence.js.map +0 -1
  339. package/lib/sharedString.d.ts.map +0 -1
  340. package/lib/sharedString.js +0 -183
  341. package/lib/sharedString.js.map +0 -1
  342. package/lib/sparsematrix.d.ts +0 -139
  343. package/lib/sparsematrix.d.ts.map +0 -1
  344. package/lib/sparsematrix.js +0 -323
  345. package/lib/sparsematrix.js.map +0 -1
  346. package/src/sharedNumberSequence.ts +0 -62
  347. package/src/sharedObjectSequence.ts +0 -62
  348. package/src/sparsematrix.ts +0 -421
  349. package/tsconfig.esnext.json +0 -7
@@ -0,0 +1,693 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /* eslint-disable no-bitwise */
7
+
8
+ import { assert, unreachableCase } from "@fluidframework/core-utils";
9
+ import {
10
+ appendToMergeTreeDeltaRevertibles,
11
+ discardMergeTreeDeltaRevertible,
12
+ isMergeTreeDeltaRevertible,
13
+ LocalReferencePosition,
14
+ MergeTreeDeltaOperationType,
15
+ MergeTreeDeltaRevertible,
16
+ MergeTreeDeltaType,
17
+ PropertySet,
18
+ ReferenceType,
19
+ refTypeIncludesFlag,
20
+ revertMergeTreeDeltaRevertibles,
21
+ // eslint-disable-next-line import/no-deprecated
22
+ SortedSet,
23
+ getSlideToSegoff,
24
+ SlidingPreference,
25
+ } from "@fluidframework/merge-tree";
26
+ import { InteriorSequencePlace, Side } from "./intervalCollection";
27
+ import { IntervalOpType, SequenceInterval } from "./intervals";
28
+ import { SharedString, SharedStringSegment } from "./sharedString";
29
+ import { ISequenceDeltaRange, SequenceDeltaEvent } from "./sequenceDeltaEvent";
30
+
31
+ /**
32
+ * Data for undoing edits on SharedStrings and Intervals.
33
+ * @internal
34
+ */
35
+ export type SharedStringRevertible = MergeTreeDeltaRevertible | IntervalRevertible;
36
+
37
+ const idMap = new Map<string, string>();
38
+
39
+ /**
40
+ * Data for undoing edits affecting Intervals.
41
+ * @internal
42
+ */
43
+ export type IntervalRevertible =
44
+ | {
45
+ event: typeof IntervalOpType.CHANGE;
46
+ interval: SequenceInterval;
47
+ start: LocalReferencePosition;
48
+ end: LocalReferencePosition;
49
+ }
50
+ | {
51
+ event: typeof IntervalOpType.ADD;
52
+ interval: SequenceInterval;
53
+ }
54
+ | {
55
+ event: typeof IntervalOpType.DELETE;
56
+ interval: SequenceInterval;
57
+ start: LocalReferencePosition;
58
+ end: LocalReferencePosition;
59
+ }
60
+ | {
61
+ event: typeof IntervalOpType.PROPERTY_CHANGED;
62
+ interval: SequenceInterval;
63
+ propertyDeltas: PropertySet;
64
+ }
65
+ | {
66
+ event: typeof IntervalOpType.POSITION_REMOVE;
67
+ intervals: {
68
+ intervalId: string;
69
+ label: string;
70
+ startOffset?: number; // interval start index within a removed range
71
+ endOffset?: number; // interval end index within a removed range
72
+ }[];
73
+ // local refs used by IntervalOpType.CHANGE and DELETE revertibles
74
+ revertibleRefs: {
75
+ revertible: IntervalRevertible;
76
+ offset: number;
77
+ isStart: boolean;
78
+ }[];
79
+ mergeTreeRevertible: MergeTreeDeltaRevertible;
80
+ };
81
+
82
+ type TypedRevertible<T extends IntervalRevertible["event"]> = IntervalRevertible & { event: T };
83
+
84
+ function getUpdatedIdFromInterval(interval: SequenceInterval): string {
85
+ const maybeId = interval.getIntervalId();
86
+ return getUpdatedId(maybeId);
87
+ }
88
+
89
+ function getUpdatedId(intervalId: string): string {
90
+ return idMap.get(intervalId) ?? intervalId;
91
+ }
92
+
93
+ /**
94
+ * Create revertibles for adding an interval
95
+ * @internal
96
+ */
97
+ export function appendAddIntervalToRevertibles(
98
+ interval: SequenceInterval,
99
+ revertibles: SharedStringRevertible[],
100
+ ) {
101
+ revertibles.push({
102
+ event: IntervalOpType.ADD,
103
+ interval,
104
+ });
105
+
106
+ return revertibles;
107
+ }
108
+
109
+ /**
110
+ * Create revertibles for deleting an interval
111
+ * @internal
112
+ */
113
+ export function appendDeleteIntervalToRevertibles(
114
+ string: SharedString,
115
+ interval: SequenceInterval,
116
+ revertibles: SharedStringRevertible[],
117
+ ): SharedStringRevertible[] {
118
+ const startSeg = interval.start.getSegment() as SharedStringSegment | undefined;
119
+ if (!startSeg) {
120
+ return revertibles;
121
+ }
122
+ const startType =
123
+ startSeg.removedSeq !== undefined
124
+ ? ReferenceType.SlideOnRemove | ReferenceType.RangeBegin
125
+ : ReferenceType.StayOnRemove | ReferenceType.RangeBegin;
126
+ const endSeg = interval.end.getSegment() as SharedStringSegment | undefined;
127
+ if (!endSeg) {
128
+ return revertibles;
129
+ }
130
+ const endType =
131
+ endSeg.removedSeq !== undefined
132
+ ? ReferenceType.SlideOnRemove | ReferenceType.RangeEnd
133
+ : ReferenceType.StayOnRemove | ReferenceType.RangeEnd;
134
+ const startRef = string.createLocalReferencePosition(
135
+ startSeg,
136
+ interval.start.getOffset(),
137
+ startType,
138
+ undefined,
139
+ interval.start.slidingPreference,
140
+ );
141
+ const endRef = string.createLocalReferencePosition(
142
+ endSeg,
143
+ interval.end.getOffset(),
144
+ endType,
145
+ undefined,
146
+ interval.end.slidingPreference,
147
+ );
148
+ const revertible = {
149
+ event: IntervalOpType.DELETE,
150
+ interval,
151
+ start: startRef,
152
+ end: endRef,
153
+ };
154
+ revertible.start.addProperties({ revertible });
155
+ revertible.end.addProperties({ revertible });
156
+ revertibles.push(revertible);
157
+
158
+ return revertibles;
159
+ }
160
+
161
+ /**
162
+ * Create revertibles for moving endpoints of an interval
163
+ * @internal
164
+ */
165
+ export function appendChangeIntervalToRevertibles(
166
+ string: SharedString,
167
+ newInterval: SequenceInterval,
168
+ previousInterval: SequenceInterval,
169
+ revertibles: SharedStringRevertible[],
170
+ ) {
171
+ const startSeg = previousInterval.start.getSegment() as SharedStringSegment;
172
+ // This logic is needed because the ReferenceType StayOnRemove cannot be used
173
+ // on removed segments. This works for revertibles because the old position of the
174
+ // interval within the removed segment is handled by the remove range revertible.
175
+ const startType =
176
+ startSeg.removedSeq !== undefined
177
+ ? ReferenceType.SlideOnRemove | ReferenceType.RangeBegin
178
+ : ReferenceType.StayOnRemove | ReferenceType.RangeBegin;
179
+ const endSeg = previousInterval.end.getSegment() as SharedStringSegment;
180
+ const endType =
181
+ endSeg.removedSeq !== undefined
182
+ ? ReferenceType.SlideOnRemove | ReferenceType.RangeEnd
183
+ : ReferenceType.StayOnRemove | ReferenceType.RangeEnd;
184
+ const prevStartRef = string.createLocalReferencePosition(
185
+ startSeg,
186
+ previousInterval.start.getOffset(),
187
+ startType,
188
+ undefined,
189
+ previousInterval.start.slidingPreference,
190
+ );
191
+ const prevEndRef = string.createLocalReferencePosition(
192
+ endSeg,
193
+ previousInterval.end.getOffset(),
194
+ endType,
195
+ undefined,
196
+ previousInterval.end.slidingPreference,
197
+ );
198
+ const revertible = {
199
+ event: IntervalOpType.CHANGE,
200
+ interval: newInterval,
201
+ start: prevStartRef,
202
+ end: prevEndRef,
203
+ };
204
+ revertible.start.addProperties({ revertible });
205
+ revertible.end.addProperties({ revertible });
206
+ revertibles.push(revertible);
207
+
208
+ return revertibles;
209
+ }
210
+
211
+ /**
212
+ * Create revertibles for changing properties of an interval
213
+ * @internal
214
+ */
215
+ export function appendIntervalPropertyChangedToRevertibles(
216
+ interval: SequenceInterval,
217
+ deltas: PropertySet,
218
+ revertibles: SharedStringRevertible[],
219
+ ) {
220
+ revertibles.push({
221
+ event: IntervalOpType.PROPERTY_CHANGED,
222
+ interval,
223
+ propertyDeltas: deltas,
224
+ });
225
+
226
+ return revertibles;
227
+ }
228
+
229
+ function addIfIntervalEndpoint(
230
+ ref: LocalReferencePosition,
231
+ segmentLengths: number,
232
+ startIntervals: { offset: number; interval: SequenceInterval }[],
233
+ endIntervals: { offset: number; interval: SequenceInterval }[],
234
+ ) {
235
+ if (refTypeIncludesFlag(ref.refType, ReferenceType.RangeBegin)) {
236
+ const interval = ref.properties?.interval;
237
+ if (interval && interval instanceof SequenceInterval) {
238
+ startIntervals.push({ offset: segmentLengths + interval.start.getOffset(), interval });
239
+ return true;
240
+ }
241
+ } else if (refTypeIncludesFlag(ref.refType, ReferenceType.RangeEnd)) {
242
+ const interval = ref.properties?.interval;
243
+ if (interval && interval instanceof SequenceInterval) {
244
+ endIntervals.push({ offset: segmentLengths + interval.end.getOffset(), interval });
245
+ return true;
246
+ }
247
+ }
248
+ return false;
249
+ }
250
+
251
+ function addIfRevertibleRef(
252
+ ref: LocalReferencePosition,
253
+ segmentLengths: number,
254
+ revertibleRefs: {
255
+ revertible: IntervalRevertible;
256
+ offset: number;
257
+ isStart: boolean;
258
+ }[],
259
+ ) {
260
+ const revertible = ref.properties?.revertible;
261
+ if (revertible) {
262
+ revertibleRefs.push({
263
+ revertible,
264
+ offset: segmentLengths + ref.getOffset(),
265
+ isStart: refTypeIncludesFlag(ref.refType, ReferenceType.RangeBegin),
266
+ });
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Create revertibles for SharedStringDeltas, handling indirectly modified intervals
272
+ * (e.g. reverting remove of a range that contains an interval will move the interval back)
273
+ * @internal
274
+ */
275
+ export function appendSharedStringDeltaToRevertibles(
276
+ string: SharedString,
277
+ delta: SequenceDeltaEvent,
278
+ revertibles: SharedStringRevertible[],
279
+ ) {
280
+ if (delta.ranges.length === 0) {
281
+ return;
282
+ }
283
+ if (delta.deltaOperation === MergeTreeDeltaType.REMOVE) {
284
+ const startIntervals: { offset: number; interval: SequenceInterval }[] = [];
285
+ const endIntervals: { offset: number; interval: SequenceInterval }[] = [];
286
+ const revertibleRefs: {
287
+ revertible: IntervalRevertible;
288
+ offset: number;
289
+ isStart: boolean;
290
+ }[] = [];
291
+ let segmentLengths = 0;
292
+
293
+ // find interval endpoints in each segment
294
+ for (const deltaRange of delta.ranges) {
295
+ const refs = deltaRange.segment.localRefs;
296
+ if (refs !== undefined && deltaRange.position !== -1) {
297
+ for (const ref of refs) {
298
+ addIfIntervalEndpoint(ref, segmentLengths, startIntervals, endIntervals);
299
+ addIfRevertibleRef(ref, segmentLengths, revertibleRefs);
300
+ }
301
+ }
302
+ segmentLengths += deltaRange.segment.cachedLength;
303
+ }
304
+
305
+ if (startIntervals.length > 0 || endIntervals.length > 0 || revertibleRefs.length > 0) {
306
+ const removeRevertibles: MergeTreeDeltaRevertible[] = [];
307
+ appendToMergeTreeDeltaRevertibles(delta.deltaArgs, removeRevertibles);
308
+ assert(
309
+ removeRevertibles.length === 1,
310
+ 0x6c4 /* Remove revertible should be a single delta */,
311
+ );
312
+
313
+ const revertible: TypedRevertible<typeof IntervalOpType.POSITION_REMOVE> = {
314
+ event: IntervalOpType.POSITION_REMOVE,
315
+ intervals: [],
316
+ revertibleRefs,
317
+ mergeTreeRevertible: removeRevertibles[0],
318
+ };
319
+
320
+ // add an interval for each startInterval, accounting for any corresponding endIntervals
321
+ startIntervals.forEach(({ interval, offset }) => {
322
+ // find any corresponding end for this interval
323
+ const endIntervalIndex = endIntervals.findIndex((end) => {
324
+ return end.interval === interval;
325
+ });
326
+ let endOffset: number | undefined;
327
+ if (endIntervalIndex !== -1) {
328
+ endOffset = endIntervals[endIntervalIndex].offset;
329
+ endIntervals.splice(endIntervalIndex, 1);
330
+ }
331
+
332
+ revertible.intervals.push({
333
+ intervalId: interval.getIntervalId(),
334
+ label: interval.properties.referenceRangeLabels[0],
335
+ startOffset: offset,
336
+ endOffset,
337
+ });
338
+ });
339
+
340
+ // add any remaining endIntervals that aren't matched with a startInterval
341
+ endIntervals.forEach(({ interval, offset }) => {
342
+ revertible.intervals.push({
343
+ intervalId: interval.getIntervalId(),
344
+ label: interval.properties.referenceRangeLabels[0],
345
+ endOffset: offset,
346
+ });
347
+ });
348
+
349
+ revertibles.push(revertible);
350
+ return;
351
+ }
352
+ }
353
+
354
+ // Handle any merge tree delta that is not REMOVE or is REMOVE with no interval endpoints
355
+ const mergeTreeRevertibles: MergeTreeDeltaRevertible[] = [];
356
+ // Allow merging MergeTreeDeltaRevertible with previous
357
+ if (revertibles.length > 0 && isMergeTreeDeltaRevertible(revertibles[revertibles.length - 1])) {
358
+ mergeTreeRevertibles.push(revertibles.pop() as MergeTreeDeltaRevertible);
359
+ }
360
+ appendToMergeTreeDeltaRevertibles(delta.deltaArgs, mergeTreeRevertibles);
361
+ revertibles.push(...mergeTreeRevertibles);
362
+ }
363
+
364
+ /**
365
+ * Clean up resources held by revertibles that are no longer needed.
366
+ * @internal
367
+ */
368
+ export function discardSharedStringRevertibles(
369
+ sharedString: SharedString,
370
+ revertibles: SharedStringRevertible[],
371
+ ) {
372
+ revertibles.forEach((r) => {
373
+ if (isMergeTreeDeltaRevertible(r)) {
374
+ discardMergeTreeDeltaRevertible([r]);
375
+ } else if (r.event === IntervalOpType.CHANGE || r.event === IntervalOpType.DELETE) {
376
+ sharedString.removeLocalReferencePosition(r.start);
377
+ sharedString.removeLocalReferencePosition(r.end);
378
+ }
379
+ });
380
+ }
381
+
382
+ function getSlidePosition(string: SharedString, lref: LocalReferencePosition, pos: number): number {
383
+ const slide = getSlideToSegoff(
384
+ { segment: lref.getSegment(), offset: undefined },
385
+ lref.slidingPreference,
386
+ );
387
+ return slide?.segment !== undefined &&
388
+ slide.offset !== undefined &&
389
+ string.getPosition(slide.segment) !== -1 &&
390
+ (pos < 0 || pos >= string.getLength())
391
+ ? string.getPosition(slide.segment) + slide.offset
392
+ : pos;
393
+ }
394
+
395
+ function isValidRange(
396
+ start: number,
397
+ startSlide: SlidingPreference | undefined,
398
+ end: number,
399
+ endSlide: SlidingPreference | undefined,
400
+ string: SharedString,
401
+ ) {
402
+ return (
403
+ start >= 0 &&
404
+ start < string.getLength() &&
405
+ end >= 0 &&
406
+ end < string.getLength() &&
407
+ (start < end ||
408
+ (start === end &&
409
+ (startSlide === SlidingPreference.FORWARD ||
410
+ endSlide !== SlidingPreference.FORWARD)))
411
+ );
412
+ }
413
+
414
+ function revertLocalAdd(
415
+ string: SharedString,
416
+ revertible: TypedRevertible<typeof IntervalOpType.ADD>,
417
+ ) {
418
+ const id = getUpdatedIdFromInterval(revertible.interval);
419
+ const label = revertible.interval.properties.referenceRangeLabels[0];
420
+ string.getIntervalCollection(label).removeIntervalById(id);
421
+ }
422
+
423
+ function createSequencePlace(
424
+ pos: number,
425
+ newSlidingPreference: SlidingPreference | undefined,
426
+ oldSlidingPreference: SlidingPreference | undefined = undefined,
427
+ ): number | InteriorSequencePlace {
428
+ return newSlidingPreference === SlidingPreference.BACKWARD ||
429
+ (newSlidingPreference === undefined && oldSlidingPreference === SlidingPreference.BACKWARD)
430
+ ? {
431
+ pos,
432
+ side: Side.After,
433
+ }
434
+ : newSlidingPreference === SlidingPreference.FORWARD &&
435
+ oldSlidingPreference === SlidingPreference.BACKWARD
436
+ ? {
437
+ pos,
438
+ side: Side.Before,
439
+ }
440
+ : pos; // Avoid setting side if possible since stickiness may not be enabled
441
+ }
442
+
443
+ function revertLocalDelete(
444
+ string: SharedString,
445
+ revertible: TypedRevertible<typeof IntervalOpType.DELETE>,
446
+ ) {
447
+ const label = revertible.interval.properties.referenceRangeLabels[0];
448
+ const collection = string.getIntervalCollection(label);
449
+ const start = string.localReferencePositionToPosition(revertible.start);
450
+ const startSlidePos = getSlidePosition(string, revertible.start, start);
451
+ const end = string.localReferencePositionToPosition(revertible.end);
452
+ const endSlidePos = getSlidePosition(string, revertible.end, end);
453
+ // reusing the id causes eventual consistency bugs, so it is removed here and recreated in add
454
+ const { intervalId, ...props } = revertible.interval.properties;
455
+ if (
456
+ isValidRange(
457
+ startSlidePos,
458
+ revertible.start.slidingPreference,
459
+ endSlidePos,
460
+ revertible.end.slidingPreference,
461
+ string,
462
+ )
463
+ ) {
464
+ const int = collection.add({
465
+ start: createSequencePlace(startSlidePos, revertible.start.slidingPreference),
466
+ end: createSequencePlace(endSlidePos, revertible.end.slidingPreference),
467
+ props,
468
+ });
469
+
470
+ idMap.forEach((newId, oldId) => {
471
+ if (intervalId === newId) {
472
+ idMap.set(oldId, getUpdatedIdFromInterval(int));
473
+ }
474
+ });
475
+ idMap.set(intervalId, int.getIntervalId());
476
+ }
477
+
478
+ string.removeLocalReferencePosition(revertible.start);
479
+ string.removeLocalReferencePosition(revertible.end);
480
+ }
481
+
482
+ function revertLocalChange(
483
+ string: SharedString,
484
+ revertible: TypedRevertible<typeof IntervalOpType.CHANGE>,
485
+ ) {
486
+ const label = revertible.interval.properties.referenceRangeLabels[0];
487
+ const collection = string.getIntervalCollection(label);
488
+ const id = getUpdatedIdFromInterval(revertible.interval);
489
+ const start = string.localReferencePositionToPosition(revertible.start);
490
+ const startSlidePos = getSlidePosition(string, revertible.start, start);
491
+ const end = string.localReferencePositionToPosition(revertible.end);
492
+ const endSlidePos = getSlidePosition(string, revertible.end, end);
493
+ const interval = collection.getIntervalById(id);
494
+ if (
495
+ interval !== undefined &&
496
+ isValidRange(
497
+ startSlidePos,
498
+ revertible.start.slidingPreference ?? interval.start.slidingPreference,
499
+ endSlidePos,
500
+ revertible.end.slidingPreference ?? interval.end.slidingPreference,
501
+ string,
502
+ )
503
+ ) {
504
+ collection.change(
505
+ id,
506
+ createSequencePlace(
507
+ startSlidePos,
508
+ revertible.start.slidingPreference,
509
+ interval.start.slidingPreference,
510
+ ),
511
+ createSequencePlace(
512
+ endSlidePos,
513
+ revertible.end.slidingPreference,
514
+ interval.end.slidingPreference,
515
+ ),
516
+ );
517
+ }
518
+
519
+ string.removeLocalReferencePosition(revertible.start);
520
+ string.removeLocalReferencePosition(revertible.end);
521
+ }
522
+
523
+ function revertLocalPropertyChanged(
524
+ string: SharedString,
525
+ revertible: TypedRevertible<typeof IntervalOpType.PROPERTY_CHANGED>,
526
+ ) {
527
+ const label = revertible.interval.properties.referenceRangeLabels[0];
528
+ const id = getUpdatedIdFromInterval(revertible.interval);
529
+ const newProps = revertible.propertyDeltas;
530
+ string.getIntervalCollection(label).changeProperties(id, newProps);
531
+ }
532
+
533
+ function newPosition(offset: number | undefined, restoredRanges: SortedRangeSet) {
534
+ if (offset === undefined) {
535
+ return undefined;
536
+ }
537
+
538
+ let offsetFromSegment = offset;
539
+ for (const rangeInfo of restoredRanges.items) {
540
+ if (offsetFromSegment < rangeInfo.length) {
541
+ // find the segment inside the range
542
+ for (const range of rangeInfo.ranges) {
543
+ if (range.segment.cachedLength > offsetFromSegment) {
544
+ return { segment: range.segment, offset: offsetFromSegment };
545
+ }
546
+ offsetFromSegment -= range.segment.cachedLength;
547
+ }
548
+ }
549
+ offsetFromSegment -= rangeInfo.length;
550
+ }
551
+
552
+ return undefined;
553
+ }
554
+
555
+ function newEndpointPosition(
556
+ offset: number | undefined,
557
+ restoredRanges: SortedRangeSet,
558
+ sharedString: SharedString,
559
+ ) {
560
+ const pos = newPosition(offset, restoredRanges);
561
+ return pos === undefined ? undefined : sharedString.getPosition(pos.segment) + pos.offset;
562
+ }
563
+
564
+ interface RangeInfo {
565
+ ranges: readonly Readonly<ISequenceDeltaRange<MergeTreeDeltaOperationType>>[];
566
+ length: number;
567
+ }
568
+
569
+ // eslint-disable-next-line import/no-deprecated
570
+ class SortedRangeSet extends SortedSet<RangeInfo, string> {
571
+ protected getKey(item: RangeInfo): string {
572
+ return item.ranges[0].segment.ordinal;
573
+ }
574
+ }
575
+
576
+ function revertLocalSequenceRemove(
577
+ sharedString: SharedString,
578
+ revertible: TypedRevertible<typeof IntervalOpType.POSITION_REMOVE>,
579
+ ) {
580
+ const restoredRanges = new SortedRangeSet();
581
+ const saveSegments = (event: SequenceDeltaEvent) => {
582
+ if (event.ranges.length > 0) {
583
+ let length = 0;
584
+ event.ranges.forEach((range) => {
585
+ length += range.segment.cachedLength;
586
+ });
587
+ restoredRanges.addOrUpdate({ ranges: event.ranges, length });
588
+ }
589
+ };
590
+ sharedString.on("sequenceDelta", saveSegments);
591
+ revertMergeTreeDeltaRevertibles(sharedString, [revertible.mergeTreeRevertible]);
592
+ sharedString.off("sequenceDelta", saveSegments);
593
+
594
+ revertible.intervals.forEach((intervalInfo) => {
595
+ const intervalCollection = sharedString.getIntervalCollection(intervalInfo.label);
596
+ const intervalId = getUpdatedId(intervalInfo.intervalId);
597
+ const interval = intervalCollection.getIntervalById(intervalId);
598
+ if (interval !== undefined) {
599
+ const start =
600
+ newEndpointPosition(intervalInfo.startOffset, restoredRanges, sharedString) ??
601
+ sharedString.localReferencePositionToPosition(interval.start);
602
+ const end =
603
+ newEndpointPosition(intervalInfo.endOffset, restoredRanges, sharedString) ??
604
+ sharedString.localReferencePositionToPosition(interval.end);
605
+ if (
606
+ isValidRange(
607
+ start,
608
+ interval.start.slidingPreference,
609
+ end,
610
+ interval.end.slidingPreference,
611
+ sharedString,
612
+ )
613
+ ) {
614
+ intervalCollection.change(
615
+ intervalId,
616
+ createSequencePlace(start, interval.start.slidingPreference),
617
+ createSequencePlace(end, interval.end.slidingPreference),
618
+ );
619
+ }
620
+ }
621
+ });
622
+
623
+ // fix up the local references used by delete and change revertibles
624
+ revertible.revertibleRefs.forEach((revertibleRef) => {
625
+ assert(
626
+ revertibleRef.revertible.event === IntervalOpType.CHANGE ||
627
+ revertibleRef.revertible.event === IntervalOpType.DELETE,
628
+ 0x6c5 /* revertible is not delete or change */,
629
+ );
630
+ const pos = newPosition(revertibleRef.offset, restoredRanges);
631
+ if (pos !== undefined) {
632
+ if (revertibleRef.isStart) {
633
+ sharedString.removeLocalReferencePosition(revertibleRef.revertible.start);
634
+ const newRef = sharedString.createLocalReferencePosition(
635
+ pos.segment as SharedStringSegment,
636
+ pos.offset,
637
+ ReferenceType.StayOnRemove | ReferenceType.RangeBegin,
638
+ { revertible: revertibleRef.revertible },
639
+ revertibleRef.revertible.start.slidingPreference,
640
+ );
641
+ revertibleRef.revertible.start = newRef;
642
+ } else {
643
+ sharedString.removeLocalReferencePosition(revertibleRef.revertible.end);
644
+ const newRef = sharedString.createLocalReferencePosition(
645
+ pos.segment as SharedStringSegment,
646
+ pos.offset,
647
+ ReferenceType.StayOnRemove | ReferenceType.RangeEnd,
648
+ { revertible: revertibleRef.revertible },
649
+ revertibleRef.revertible.end.slidingPreference,
650
+ );
651
+ revertibleRef.revertible.end = newRef;
652
+ }
653
+ }
654
+ });
655
+ }
656
+
657
+ /**
658
+ * Invoke revertibles to reverse prior edits
659
+ * @internal
660
+ */
661
+ export function revertSharedStringRevertibles(
662
+ sharedString: SharedString,
663
+ revertibles: SharedStringRevertible[],
664
+ ) {
665
+ while (revertibles.length > 0) {
666
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
667
+ const r = revertibles.pop()!;
668
+ if ("event" in r) {
669
+ const event = r.event;
670
+ switch (event) {
671
+ case IntervalOpType.ADD:
672
+ revertLocalAdd(sharedString, r);
673
+ break;
674
+ case IntervalOpType.DELETE:
675
+ revertLocalDelete(sharedString, r);
676
+ break;
677
+ case IntervalOpType.CHANGE:
678
+ revertLocalChange(sharedString, r);
679
+ break;
680
+ case IntervalOpType.PROPERTY_CHANGED:
681
+ revertLocalPropertyChanged(sharedString, r);
682
+ break;
683
+ case IntervalOpType.POSITION_REMOVE:
684
+ revertLocalSequenceRemove(sharedString, r);
685
+ break;
686
+ default:
687
+ unreachableCase(event);
688
+ }
689
+ } else {
690
+ revertMergeTreeDeltaRevertibles(sharedString, [r]);
691
+ }
692
+ }
693
+ }