@fluidframework/sequence 1.4.0-115997 → 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,616 @@
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
+ /* eslint-disable import/no-deprecated */
8
+
9
+ import {
10
+ Client,
11
+ ISegment,
12
+ LocalReferencePosition,
13
+ PropertiesManager,
14
+ PropertySet,
15
+ ReferenceType,
16
+ SlidingPreference,
17
+ compareReferencePositions,
18
+ createDetachedLocalReferencePosition,
19
+ createMap,
20
+ getSlideToSegoff,
21
+ maxReferencePosition,
22
+ minReferencePosition,
23
+ refTypeIncludesFlag,
24
+ reservedRangeLabelsKey,
25
+ } from "@fluidframework/merge-tree";
26
+ import { assert } from "@fluidframework/core-utils";
27
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
28
+ import { UsageError } from "@fluidframework/telemetry-utils";
29
+ import {
30
+ SequencePlace,
31
+ Side,
32
+ computeStickinessFromSide,
33
+ endpointPosAndSide,
34
+ sidesFromStickiness,
35
+ } from "../intervalCollection";
36
+ import {
37
+ IIntervalHelpers,
38
+ ISerializableInterval,
39
+ ISerializedInterval,
40
+ IntervalStickiness,
41
+ IntervalType,
42
+ endReferenceSlidingPreference,
43
+ startReferenceSlidingPreference,
44
+ } from "./intervalUtils";
45
+
46
+ const reservedIntervalIdKey = "intervalId";
47
+
48
+ function compareSides(sideA: Side, sideB: Side): number {
49
+ if (sideA === sideB) {
50
+ return 0;
51
+ }
52
+
53
+ if (sideA === Side.Before) {
54
+ return 1;
55
+ }
56
+
57
+ return -1;
58
+ }
59
+
60
+ function minSide(sideA: Side, sideB: Side): Side {
61
+ if (sideA === Side.After && sideB === Side.After) {
62
+ return Side.After;
63
+ }
64
+
65
+ return Side.Before;
66
+ }
67
+
68
+ function maxSide(sideA: Side, sideB: Side): Side {
69
+ if (sideA === Side.Before && sideB === Side.Before) {
70
+ return Side.Before;
71
+ }
72
+
73
+ return Side.After;
74
+ }
75
+
76
+ /**
77
+ * Interval implementation whose ends are associated with positions in a mutatable sequence.
78
+ * As such, when content is inserted into the middle of the interval, the interval expands to
79
+ * include that content.
80
+ *
81
+ * @remarks The endpoints' positions should be treated exclusively to get
82
+ * reasonable behavior. E.g., an interval referring to "hello" in "hello world"
83
+ * should have a start position of 0 and an end position of 5.
84
+ *
85
+ * To see why, consider what happens if "llo wor" is removed from the string to make "held".
86
+ * The interval's startpoint remains on the "h" (it isn't altered), but the interval's endpoint
87
+ * slides forward to the next unremoved position, which is the "l" in "held".
88
+ * Users would generally expect the interval to now refer to "he" (as it is the subset of content
89
+ * remaining after the removal), hence the "l" should be excluded.
90
+ * If the interval endpoint was treated inclusively, the interval would now refer to "hel", which
91
+ * is undesirable.
92
+ *
93
+ * Since the endpoints of an interval are treated exclusively but cannot be greater
94
+ * than or equal to the length of the associated sequence, there exist special
95
+ * endpoint segments, "start" and "end", which represent the position immediately
96
+ * before or immediately after the string respectively.
97
+ *
98
+ * If a `SequenceInterval` is created on a sequence with the
99
+ * `mergeTreeReferencesCanSlideToEndpoint` feature flag set to true, the endpoints
100
+ * of the interval that are exclusive will have the ability to slide to these
101
+ * special endpoint segments.
102
+ * @alpha
103
+ */
104
+ export class SequenceInterval implements ISerializableInterval {
105
+ /**
106
+ * {@inheritDoc ISerializableInterval.properties}
107
+ */
108
+ public properties: PropertySet = createMap<any>();
109
+
110
+ /**
111
+ * {@inheritDoc ISerializableInterval.propertyManager}
112
+ */
113
+ public propertyManager: PropertiesManager = new PropertiesManager();
114
+
115
+ /***/
116
+ public get stickiness(): IntervalStickiness {
117
+ const startSegment = this.start.getSegment();
118
+ const endSegment = this.end.getSegment();
119
+ return computeStickinessFromSide(
120
+ startSegment?.endpointType,
121
+ this.startSide,
122
+ endSegment?.endpointType,
123
+ this.endSide,
124
+ );
125
+ }
126
+
127
+ constructor(
128
+ private readonly client: Client,
129
+ /**
130
+ * Start endpoint of this interval.
131
+ * @remarks This endpoint can be resolved into a character position using the SharedString it's a part of.
132
+ */
133
+ public start: LocalReferencePosition,
134
+ /**
135
+ * End endpoint of this interval.
136
+ * @remarks This endpoint can be resolved into a character position using the SharedString it's a part of.
137
+ */
138
+ public end: LocalReferencePosition,
139
+ public intervalType: IntervalType,
140
+ props?: PropertySet,
141
+ public readonly startSide: Side = Side.Before,
142
+ public readonly endSide: Side = Side.Before,
143
+ ) {
144
+ if (props) {
145
+ this.addProperties(props);
146
+ }
147
+ }
148
+
149
+ private callbacks?: Record<"beforePositionChange" | "afterPositionChange", () => void>;
150
+
151
+ /**
152
+ * Subscribes to position change events on this interval if there are no current listeners.
153
+ */
154
+ public addPositionChangeListeners(
155
+ beforePositionChange: () => void,
156
+ afterPositionChange: () => void,
157
+ ): void {
158
+ if (this.callbacks === undefined) {
159
+ this.callbacks = {
160
+ beforePositionChange,
161
+ afterPositionChange,
162
+ };
163
+
164
+ const startCbs = (this.start.callbacks ??= {});
165
+ const endCbs = (this.end.callbacks ??= {});
166
+ startCbs.beforeSlide = endCbs.beforeSlide = beforePositionChange;
167
+ startCbs.afterSlide = endCbs.afterSlide = afterPositionChange;
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Removes the currently subscribed position change listeners.
173
+ */
174
+ public removePositionChangeListeners(): void {
175
+ if (this.callbacks) {
176
+ this.callbacks = undefined;
177
+ this.start.callbacks = undefined;
178
+ this.end.callbacks = undefined;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * {@inheritDoc ISerializableInterval.serialize}
184
+ */
185
+ public serialize(): ISerializedInterval {
186
+ const startPosition = this.client.localReferencePositionToPosition(this.start);
187
+ const endPosition = this.client.localReferencePositionToPosition(this.end);
188
+ const { startSide, endSide } = sidesFromStickiness(this.stickiness);
189
+ const serializedInterval: ISerializedInterval = {
190
+ end: endPosition,
191
+ intervalType: this.intervalType,
192
+ sequenceNumber: this.client.getCurrentSeq(),
193
+ start: startPosition,
194
+ stickiness: this.stickiness,
195
+ startSide,
196
+ endSide,
197
+ };
198
+
199
+ if (this.properties) {
200
+ serializedInterval.properties = this.properties;
201
+ }
202
+
203
+ return serializedInterval;
204
+ }
205
+
206
+ /**
207
+ * {@inheritDoc IInterval.clone}
208
+ */
209
+ public clone() {
210
+ return new SequenceInterval(
211
+ this.client,
212
+ this.start,
213
+ this.end,
214
+ this.intervalType,
215
+ this.properties,
216
+ this.startSide,
217
+ this.endSide,
218
+ );
219
+ }
220
+
221
+ /**
222
+ * {@inheritDoc IInterval.compare}
223
+ */
224
+ public compare(b: SequenceInterval) {
225
+ const startResult = this.compareStart(b);
226
+ if (startResult === 0) {
227
+ const endResult = this.compareEnd(b);
228
+ if (endResult === 0) {
229
+ const thisId = this.getIntervalId();
230
+ if (thisId) {
231
+ const bId = b.getIntervalId();
232
+ if (bId) {
233
+ return thisId > bId ? 1 : thisId < bId ? -1 : 0;
234
+ }
235
+ return 0;
236
+ }
237
+ return 0;
238
+ } else {
239
+ return endResult;
240
+ }
241
+ } else {
242
+ return startResult;
243
+ }
244
+ }
245
+
246
+ /**
247
+ * {@inheritDoc IInterval.compareStart}
248
+ */
249
+ public compareStart(b: SequenceInterval) {
250
+ const dist = compareReferencePositions(this.start, b.start);
251
+
252
+ if (dist === 0) {
253
+ return compareSides(this.startSide, b.startSide);
254
+ }
255
+
256
+ return dist;
257
+ }
258
+
259
+ /**
260
+ * {@inheritDoc IInterval.compareEnd}
261
+ */
262
+ public compareEnd(b: SequenceInterval): number {
263
+ const dist = compareReferencePositions(this.end, b.end);
264
+
265
+ if (dist === 0) {
266
+ return compareSides(b.endSide, this.endSide);
267
+ }
268
+
269
+ return dist;
270
+ }
271
+
272
+ /**
273
+ * {@inheritDoc IInterval.overlaps}
274
+ */
275
+ public overlaps(b: SequenceInterval) {
276
+ const result =
277
+ compareReferencePositions(this.start, b.end) <= 0 &&
278
+ compareReferencePositions(this.end, b.start) >= 0;
279
+ return result;
280
+ }
281
+
282
+ /**
283
+ * {@inheritDoc ISerializableInterval.getIntervalId}
284
+ */
285
+ public getIntervalId(): string {
286
+ const id = this.properties?.[reservedIntervalIdKey];
287
+ assert(id !== undefined, 0x5e2 /* interval ID should not be undefined */);
288
+ return `${id}`;
289
+ }
290
+
291
+ /**
292
+ * {@inheritDoc IInterval.union}
293
+ */
294
+ public union(b: SequenceInterval) {
295
+ const newStart = minReferencePosition(this.start, b.start);
296
+ const newEnd = maxReferencePosition(this.end, b.end);
297
+
298
+ let startSide: Side;
299
+
300
+ if (this.start === b.start) {
301
+ startSide = minSide(this.startSide, b.startSide);
302
+ } else {
303
+ startSide = this.start === newStart ? this.startSide : b.startSide;
304
+ }
305
+
306
+ let endSide: Side;
307
+
308
+ if (this.end === b.end) {
309
+ endSide = maxSide(this.endSide, b.endSide);
310
+ } else {
311
+ endSide = this.end === newEnd ? this.endSide : b.endSide;
312
+ }
313
+
314
+ return new SequenceInterval(
315
+ this.client,
316
+ newStart,
317
+ newEnd,
318
+ this.intervalType,
319
+ undefined,
320
+ startSide,
321
+ endSide,
322
+ );
323
+ }
324
+
325
+ /**
326
+ * {@inheritDoc ISerializableInterval.addProperties}
327
+ */
328
+ public addProperties(
329
+ newProps: PropertySet,
330
+ collab: boolean = false,
331
+ seq?: number,
332
+ ): PropertySet | undefined {
333
+ return this.propertyManager.addProperties(this.properties, newProps, seq, collab);
334
+ }
335
+
336
+ /**
337
+ * @returns whether this interval overlaps two numerical positions.
338
+ */
339
+ public overlapsPos(bstart: number, bend: number) {
340
+ const startPos = this.client.localReferencePositionToPosition(this.start);
341
+ const endPos = this.client.localReferencePositionToPosition(this.end);
342
+ return endPos > bstart && startPos < bend;
343
+ }
344
+
345
+ /**
346
+ * {@inheritDoc IInterval.modify}
347
+ */
348
+ public modify(
349
+ label: string,
350
+ start: SequencePlace | undefined,
351
+ end: SequencePlace | undefined,
352
+ op?: ISequencedDocumentMessage,
353
+ localSeq?: number,
354
+ useNewSlidingBehavior: boolean = false,
355
+ ) {
356
+ const { startSide, endSide, startPos, endPos } = endpointPosAndSide(start, end);
357
+ const stickiness = computeStickinessFromSide(
358
+ startPos ?? this.start.getSegment()?.endpointType,
359
+ startSide ?? this.startSide,
360
+ endPos ?? this.end.getSegment()?.endpointType,
361
+ endSide ?? this.endSide,
362
+ );
363
+ const getRefType = (baseType: ReferenceType): ReferenceType => {
364
+ let refType = baseType;
365
+ if (op === undefined) {
366
+ refType &= ~ReferenceType.SlideOnRemove;
367
+ refType |= ReferenceType.StayOnRemove;
368
+ }
369
+ return refType;
370
+ };
371
+
372
+ let startRef = this.start;
373
+ if (startPos !== undefined) {
374
+ startRef = createPositionReference(
375
+ this.client,
376
+ startPos,
377
+ getRefType(this.start.refType),
378
+ op,
379
+ undefined,
380
+ localSeq,
381
+ startReferenceSlidingPreference(stickiness),
382
+ startReferenceSlidingPreference(stickiness) === SlidingPreference.BACKWARD,
383
+ useNewSlidingBehavior,
384
+ );
385
+ if (this.start.properties) {
386
+ startRef.addProperties(this.start.properties);
387
+ }
388
+ }
389
+
390
+ let endRef = this.end;
391
+ if (endPos !== undefined) {
392
+ endRef = createPositionReference(
393
+ this.client,
394
+ endPos,
395
+ getRefType(this.end.refType),
396
+ op,
397
+ undefined,
398
+ localSeq,
399
+ endReferenceSlidingPreference(stickiness),
400
+ endReferenceSlidingPreference(stickiness) === SlidingPreference.FORWARD,
401
+ useNewSlidingBehavior,
402
+ );
403
+ if (this.end.properties) {
404
+ endRef.addProperties(this.end.properties);
405
+ }
406
+ }
407
+
408
+ const newInterval = new SequenceInterval(
409
+ this.client,
410
+ startRef,
411
+ endRef,
412
+ this.intervalType,
413
+ undefined,
414
+ startSide ?? this.startSide,
415
+ endSide ?? this.endSide,
416
+ );
417
+ if (this.properties) {
418
+ this.propertyManager.copyTo(
419
+ this.properties,
420
+ newInterval.properties,
421
+ newInterval.propertyManager,
422
+ );
423
+ }
424
+ return newInterval;
425
+ }
426
+ }
427
+
428
+ export function createPositionReferenceFromSegoff(
429
+ client: Client,
430
+ segoff: { segment: ISegment | undefined; offset: number | undefined } | "start" | "end",
431
+ refType: ReferenceType,
432
+ op?: ISequencedDocumentMessage,
433
+ localSeq?: number,
434
+ fromSnapshot?: boolean,
435
+ slidingPreference?: SlidingPreference,
436
+ canSlideToEndpoint?: boolean,
437
+ ): LocalReferencePosition {
438
+ if (segoff === "start" || segoff === "end") {
439
+ return client.createLocalReferencePosition(
440
+ segoff,
441
+ undefined,
442
+ refType,
443
+ undefined,
444
+ slidingPreference,
445
+ canSlideToEndpoint,
446
+ );
447
+ }
448
+
449
+ if (segoff.segment) {
450
+ const ref = client.createLocalReferencePosition(
451
+ segoff.segment,
452
+ segoff.offset,
453
+ refType,
454
+ undefined,
455
+ slidingPreference,
456
+ canSlideToEndpoint,
457
+ );
458
+ return ref;
459
+ }
460
+
461
+ // Creating references on detached segments is allowed for:
462
+ // - Transient segments
463
+ // - References coming from a remote client (location may have been concurrently removed)
464
+ // - References being rebased to a new sequence number
465
+ // (segment they originally referred to may have been removed with no suitable replacement)
466
+ if (
467
+ !op &&
468
+ !localSeq &&
469
+ !fromSnapshot &&
470
+ !refTypeIncludesFlag(refType, ReferenceType.Transient)
471
+ ) {
472
+ throw new UsageError("Non-transient references need segment");
473
+ }
474
+
475
+ return createDetachedLocalReferencePosition(refType);
476
+ }
477
+
478
+ function createPositionReference(
479
+ client: Client,
480
+ pos: number | "start" | "end",
481
+ refType: ReferenceType,
482
+ op?: ISequencedDocumentMessage,
483
+ fromSnapshot?: boolean,
484
+ localSeq?: number,
485
+ slidingPreference?: SlidingPreference,
486
+ exclusive: boolean = false,
487
+ useNewSlidingBehavior: boolean = false,
488
+ ): LocalReferencePosition {
489
+ let segoff;
490
+
491
+ if (op) {
492
+ assert(
493
+ (refType & ReferenceType.SlideOnRemove) !== 0,
494
+ 0x2f5 /* op create references must be SlideOnRemove */,
495
+ );
496
+ if (pos === "start" || pos === "end") {
497
+ segoff = pos;
498
+ } else {
499
+ segoff = client.getContainingSegment(pos, {
500
+ referenceSequenceNumber: op.referenceSequenceNumber,
501
+ clientId: op.clientId,
502
+ });
503
+ segoff = getSlideToSegoff(segoff, undefined, useNewSlidingBehavior);
504
+ }
505
+ } else {
506
+ assert(
507
+ (refType & ReferenceType.SlideOnRemove) === 0 || !!fromSnapshot,
508
+ 0x2f6 /* SlideOnRemove references must be op created */,
509
+ );
510
+ segoff =
511
+ pos === "start" || pos === "end"
512
+ ? pos
513
+ : client.getContainingSegment(pos, undefined, localSeq);
514
+ }
515
+
516
+ return createPositionReferenceFromSegoff(
517
+ client,
518
+ segoff,
519
+ refType,
520
+ op,
521
+ localSeq,
522
+ fromSnapshot,
523
+ slidingPreference,
524
+ exclusive,
525
+ );
526
+ }
527
+
528
+ export function createSequenceInterval(
529
+ label: string,
530
+ start: SequencePlace | undefined,
531
+ end: SequencePlace | undefined,
532
+ client: Client,
533
+ intervalType: IntervalType,
534
+ op?: ISequencedDocumentMessage,
535
+ fromSnapshot?: boolean,
536
+ useNewSlidingBehavior: boolean = false,
537
+ ): SequenceInterval {
538
+ const { startPos, startSide, endPos, endSide } = endpointPosAndSide(
539
+ start ?? "start",
540
+ end ?? "end",
541
+ );
542
+ assert(
543
+ startPos !== undefined &&
544
+ endPos !== undefined &&
545
+ startSide !== undefined &&
546
+ endSide !== undefined,
547
+ 0x794 /* start and end cannot be undefined because they were not passed in as undefined */,
548
+ );
549
+ const stickiness = computeStickinessFromSide(startPos, startSide, endPos, endSide);
550
+ let beginRefType = ReferenceType.RangeBegin;
551
+ let endRefType = ReferenceType.RangeEnd;
552
+ if (intervalType === IntervalType.Transient) {
553
+ beginRefType = ReferenceType.Transient;
554
+ endRefType = ReferenceType.Transient;
555
+ } else {
556
+ // All non-transient interval references must eventually be SlideOnRemove
557
+ // To ensure eventual consistency, they must start as StayOnRemove when
558
+ // pending (created locally and creation op is not acked)
559
+ if (op ?? fromSnapshot) {
560
+ beginRefType |= ReferenceType.SlideOnRemove;
561
+ endRefType |= ReferenceType.SlideOnRemove;
562
+ } else {
563
+ beginRefType |= ReferenceType.StayOnRemove;
564
+ endRefType |= ReferenceType.StayOnRemove;
565
+ }
566
+ }
567
+
568
+ const startLref = createPositionReference(
569
+ client,
570
+ startPos,
571
+ beginRefType,
572
+ op,
573
+ fromSnapshot,
574
+ undefined,
575
+ startReferenceSlidingPreference(stickiness),
576
+ startReferenceSlidingPreference(stickiness) === SlidingPreference.BACKWARD,
577
+ useNewSlidingBehavior,
578
+ );
579
+
580
+ const endLref = createPositionReference(
581
+ client,
582
+ endPos,
583
+ endRefType,
584
+ op,
585
+ fromSnapshot,
586
+ undefined,
587
+ endReferenceSlidingPreference(stickiness),
588
+ endReferenceSlidingPreference(stickiness) === SlidingPreference.FORWARD,
589
+ useNewSlidingBehavior,
590
+ );
591
+
592
+ const rangeProp = {
593
+ [reservedRangeLabelsKey]: [label],
594
+ };
595
+ startLref.addProperties(rangeProp);
596
+ endLref.addProperties(rangeProp);
597
+
598
+ const ival = new SequenceInterval(
599
+ client,
600
+ startLref,
601
+ endLref,
602
+ intervalType,
603
+ rangeProp,
604
+ startSide,
605
+ endSide,
606
+ );
607
+ return ival;
608
+ }
609
+
610
+ /**
611
+ * @deprecated The methods within have substitutions
612
+ * @internal
613
+ */
614
+ export const sequenceIntervalHelpers: IIntervalHelpers<SequenceInterval> = {
615
+ create: createSequenceInterval,
616
+ };