@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
package/README.md CHANGED
@@ -1,25 +1,48 @@
1
1
  # @fluidframework/sequence
2
2
 
3
+ <!-- AUTO-GENERATED-CONTENT:START (README_DEPENDENCY_GUIDELINES_SECTION:includeHeading=TRUE) -->
4
+
5
+ <!-- prettier-ignore-start -->
6
+ <!-- NOTE: This section is automatically generated using @fluid-tools/markdown-magic. Do not update these generated contents directly. -->
7
+
8
+ ## Using Fluid Framework libraries
9
+
10
+ When taking a dependency on a Fluid Framework library, we recommend using a `^` (caret) version range, such as `^1.3.4`.
11
+ While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
12
+ library consumers should always prefer `^`.
13
+
14
+ Note that when depending on a library version of the form `2.0.0-internal.x.y.z`, called the Fluid internal version scheme,
15
+ you must use a `>= <` dependency range (such as `>=2.0.0-internal.x.y.z <2.0.0-internal.w.0.0` where `w` is `x+1`).
16
+ Standard `^` and `~` ranges will not work as expected.
17
+ See the [@fluid-tools/version-tools](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/version-tools/README.md)
18
+ package for more information including tools to convert between version schemes.
19
+
20
+ <!-- prettier-ignore-end -->
21
+
22
+ <!-- AUTO-GENERATED-CONTENT:END -->
23
+
24
+ ## Description
25
+
3
26
  The **@fluidframework/sequence** package supports distributed data structures which are list-like.
4
27
  Its main export is [SharedString][], a DDS for storing and simultaneously editing a sequence of text.
5
28
 
6
29
  Note that SharedString is a sequence DDS but it has additional specialized features and behaviors for working with text.
7
30
 
8
31
  This package historically contained several other sequence-based DDSes, but because they have unintuitive behaviors,
9
- they are deprecated and being moved to the *experimental* folder.
32
+ they are deprecated and being moved to the _experimental_ folder.
10
33
 
11
- The main reason for this is the lack of *move* semantics within the sequence, which becomes crucial when dealing with sequences of
34
+ The main reason for this is the lack of _move_ semantics within the sequence, which becomes crucial when dealing with sequences of
12
35
  complex content.
13
36
  For that reason, all of the examples in this README use `SharedString`. However, the APIs discussed are available on the common base class: `SharedSegmentSequence`.
14
37
 
15
- For the remainder of this document, the term *sequence* will refer to this base class.
38
+ For the remainder of this document, the term _sequence_ will refer to this base class.
16
39
 
17
- *Item*s are the individual units that are stored within the sequence (e.g. in a SharedString, the items are characters),
18
- but regardless of the type of data stored in the sequence, every item in a sequence is at a specific *position* starting
40
+ _Items_ are the individual units that are stored within the sequence (e.g. in a SharedString, the items are characters),
41
+ but regardless of the type of data stored in the sequence, every item in a sequence is at a specific _position_ starting
19
42
  at 0, similar to an array. However, sequences differ from arrays in that the positions can move as local and remote
20
43
  editors make modifications to the sequence.
21
44
 
22
- As its name suggests, SharedSegmentSequence is composed of *segments*. Segments are the unit that the sequence works
45
+ As its name suggests, SharedSegmentSequence is composed of _segments_. Segments are the unit that the sequence works
23
46
  with internally, and contain items within them. Thus, every segment has a length of at least 1 -- that is, it contains
24
47
  at least one item -- and segments may be split and merged arbitrarily as the sequence is edited. This means the length
25
48
  of the sequence is not the number of segments, but rather the sum of the length of all the segments.
@@ -63,49 +86,45 @@ can be any position in the sequence including 0, to insert at the beginning of t
63
86
  sequence, to insert at the end.
64
87
 
65
88
  ```typescript
66
- // content:
67
- // positions:
68
-
69
- // insert text at position 0
70
- sharedString.insertText(0, "hi");
71
- // content: hi
72
- // positions: 01
73
-
74
- // insert text at the end position
75
- sharedString.insertText(
76
- sharedString.getLength(),
77
- "!");
78
- // content: hi!
79
- // positions: 012
80
-
81
- // insert text at position 2
82
- sharedString.insertText(
83
- 2,
84
- " world");
85
- // content: hi world!
86
- // positions: 012345678
89
+ // content:
90
+ // positions:
91
+
92
+ // insert text at position 0
93
+ sharedString.insertText(0, "hi");
94
+ // content: hi
95
+ // positions: 01
96
+
97
+ // insert text at the end position
98
+ sharedString.insertText(sharedString.getLength(), "!");
99
+ // content: hi!
100
+ // positions: 012
101
+
102
+ // insert text at position 2
103
+ sharedString.insertText(2, " world");
104
+ // content: hi world!
105
+ // positions: 012345678
87
106
  ```
88
107
 
89
108
  ### Remove
90
109
 
91
- Remove operations take a start and an end position, referred to as a *range*. The start position is inclusive and can be
110
+ Remove operations take a start and an end position, referred to as a _range_. The start position is inclusive and can be
92
111
  any position in the sequence from 0 to its `length - 1`. The start position cannot be the length of the sequence like it
93
112
  can in insert, because there is nothing at that position. The end position is exclusive and must be greater than the
94
- start, so it can be any value from 1 to *n* (where *n* is the length of the sequence).
113
+ start, so it can be any value from 1 to _n_ (where _n_ is the length of the sequence).
95
114
 
96
115
  ```typescript
97
- // content: hi world!
98
- // positions: 012345678
99
-
100
- // remove the first 3 characters
101
- sharedString.removeRange(0, 3);
102
- // content: world!
103
- // positions: 012345
104
-
105
- // remove all the characters
106
- sharedString.removeRange(0, sharedString.getLength());
107
- // content:
108
- // positions:
116
+ // content: hi world!
117
+ // positions: 012345678
118
+
119
+ // remove the first 3 characters
120
+ sharedString.removeRange(0, 3);
121
+ // content: world!
122
+ // positions: 012345
123
+
124
+ // remove all the characters
125
+ sharedString.removeRange(0, sharedString.getLength());
126
+ // content:
127
+ // positions:
109
128
  ```
110
129
 
111
130
  ### Annotate
@@ -117,64 +136,58 @@ also takes a map-like properties object. Each key of the provided properties obj
117
136
  specified range. Setting a property key to null will remove that property from the positions in the range.
118
137
 
119
138
  ```typescript
120
- // content: hi world
121
- // positions: 01234567
122
-
123
- let props1 = sharedString.getPropertiesAtPosition(1);
124
- let props5 = sharedString.getPropertiesAtPosition(5);
125
- // props1 = {}
126
- // props5 = {}
127
-
128
- // set property called weight on positions 0 and 1
129
- sharedString.annotateRange(0, 2, { weight: 5 });
130
- props1 = sharedString.getPropertiesAtPosition(1);
131
- props5 = sharedString.getPropertiesAtPosition(5);
132
- // props1 = { weight: 5 }
133
- // props5 = {}
134
-
135
- // set property called decoration on all positions
136
- sharedString.annotateRange(
137
- 0,
138
- sharedString.getLength(),
139
- { decoration: "underline" });
140
- props1 = sharedString.getPropertiesAtPosition(1);
141
- props5 = sharedString.getPropertiesAtPosition(5);
142
- // props1 = { weight: 5, decoration: "underline" }
143
- // props5 = { decoration: "underline" }
144
-
145
- // remove property called weight on all positions
146
- sharedString.annotateRange(
147
- 0,
148
- sharedString.getLength(),
149
- { weight: null });
150
- props1 = sharedString.getPropertiesAtPosition(1);
151
- props5 = sharedString.getPropertiesAtPosition(5);
152
- // props1 = { decoration: "underline" }
153
- // props5 = { decoration: "underline" }
139
+ // content: hi world
140
+ // positions: 01234567
141
+
142
+ let props1 = sharedString.getPropertiesAtPosition(1);
143
+ let props5 = sharedString.getPropertiesAtPosition(5);
144
+ // props1 = {}
145
+ // props5 = {}
146
+
147
+ // set property called weight on positions 0 and 1
148
+ sharedString.annotateRange(0, 2, { weight: 5 });
149
+ props1 = sharedString.getPropertiesAtPosition(1);
150
+ props5 = sharedString.getPropertiesAtPosition(5);
151
+ // props1 = { weight: 5 }
152
+ // props5 = {}
153
+
154
+ // set property called decoration on all positions
155
+ sharedString.annotateRange(0, sharedString.getLength(), { decoration: "underline" });
156
+ props1 = sharedString.getPropertiesAtPosition(1);
157
+ props5 = sharedString.getPropertiesAtPosition(5);
158
+ // props1 = { weight: 5, decoration: "underline" }
159
+ // props5 = { decoration: "underline" }
160
+
161
+ // remove property called weight on all positions
162
+ sharedString.annotateRange(0, sharedString.getLength(), { weight: null });
163
+ props1 = sharedString.getPropertiesAtPosition(1);
164
+ props5 = sharedString.getPropertiesAtPosition(5);
165
+ // props1 = { decoration: "underline" }
166
+ // props5 = { decoration: "underline" }
154
167
  ```
155
168
 
156
169
  ### Sequence delta event
157
170
 
158
- Whenever an operation is performed on a sequence a *sequenceDelta* event will be raised. This event provides the ranges
159
- affected by the operation, the type of the operation, and the properties that were changes by the operation.
171
+ Whenever an operation is performed on a sequence a _sequenceDelta_ event will be raised. This event provides the ranges
172
+ affected by the operation, the type of the operation, and the properties that were changed by the operation.
160
173
 
161
174
  ```typescript
162
175
  sharedString.on("sequenceDelta", ({ deltaOperation, ranges, isLocal }) => {
163
- if (isLocal) {
164
- // undo-redo implementations frequently will only concern themselves with local ops: only operations submitted
165
- // by the local client should be undoable by the current user
166
- addOperationToUndoStack(deltaOperation, ranges);
167
- }
176
+ if (isLocal) {
177
+ // undo-redo implementations frequently will only concern themselves with local ops: only operations submitted
178
+ // by the local client should be undoable by the current user
179
+ addOperationToUndoStack(deltaOperation, ranges);
180
+ }
168
181
 
169
- if (deltaOperation === MergeTreeDeltaType.INSERT) {
170
- syncInsertSegmentToModel(deltaOperation, ranges);
171
- }
182
+ if (deltaOperation === MergeTreeDeltaType.INSERT) {
183
+ syncInsertSegmentToModel(deltaOperation, ranges);
184
+ }
172
185
 
173
- // realistic app code would likely handle the other deltaOperation types as well here.
186
+ // realistic app code would likely handle the other deltaOperation types as well here.
174
187
  });
175
188
  ```
176
189
 
177
- Internally, the sequence package depends on `@fluidframework/merge-tree`, and also raises `MergeTreeMaintenance` events on that tree as *maintenance* events.
190
+ Internally, the sequence package depends on `@fluidframework/merge-tree`, and also raises `MergeTreeMaintenance` events on that tree as _maintenance_ events.
178
191
  These events don't correspond directly to APIs invoked on a sequence DDS, but may be useful for advanced users.
179
192
 
180
193
  Both sequenceDelta and maintenance events are commonly used to synchronize or invalidate a view an application might have over a backing sequence DDS.
@@ -196,7 +209,7 @@ Consider a sequence like this:
196
209
  ```
197
210
 
198
211
  Now two users simultaneously insert characters at the end of the sequence. One inserts `k` and the other inserts a `c`.
199
- This is an *insert conflict*. The basic strategy for insert conflict resolution in the sequence is to merge *far*,
212
+ This is an _insert conflict_. The basic strategy for insert conflict resolution in the sequence is to merge _far_,
200
213
  closer to the end of the sequence.
201
214
 
202
215
  This merge strategy is possible because of a fundamental property of the Fluid Framework, which is guaranteed ordering.
@@ -278,53 +291,53 @@ determine the value.
278
291
 
279
292
  ## Local references
280
293
 
281
- Sequences support addition and manipulation of *local references* to locally track positions in the sequence over time.
294
+ Sequences support addition and manipulation of _local references_ to locally track positions in the sequence over time.
282
295
  As the name suggests, any created references will only exist locally; other clients will not see them.
283
296
  This can be used to implement user interactions with sequence data in a way that is robust to concurrent editing.
284
297
  For example, consider a text editor which tracks a user's cursor state.
285
298
  The application can store a local reference to the character after the cursor position:
286
299
 
287
300
  ```typescript
288
- // content: hi world!
289
- // positions: 012345678
290
- const { segment, offset } = sharedString.getContainingSegment(5)
291
- const cursor = sharedString.createLocalReferencePosition(
292
- segment,
293
- offset,
294
- ReferenceType.SlideOnRemove,
295
- /* any additional properties */ { cursorColor: 'blue' }
296
- );
297
-
298
- // cursor: x
299
- // content: hi world!
300
- // positions: 012345678
301
-
302
- // ... in some view code, retrieve the position of the local reference for rendering:
303
- const pos = sharedString.localReferencePositionToPosition(cursor); // 5
304
-
305
- // meanwhile, some other client submits an edit which gets applied to our string:
306
- otherSharedString.replaceText(1, 2, "ello");
307
-
308
- // The local sharedString state will now look like this:
309
- // cursor: x
310
- // content: hello world!
311
- // positions: 0123456789AB (hex)
312
-
313
- // ... in some view code, retrieve the position of the local reference for rendering:
314
- const pos = sharedString.localReferencePositionToPosition(cursor); // 8
301
+ // content: hi world!
302
+ // positions: 012345678
303
+ const { segment, offset } = sharedString.getContainingSegment(5);
304
+ const cursor = sharedString.createLocalReferencePosition(
305
+ segment,
306
+ offset,
307
+ ReferenceType.SlideOnRemove,
308
+ /* any additional properties */ { cursorColor: "blue" },
309
+ );
310
+
311
+ // cursor: x
312
+ // content: hi world!
313
+ // positions: 012345678
314
+
315
+ // ... in some view code, retrieve the position of the local reference for rendering:
316
+ const pos = sharedString.localReferencePositionToPosition(cursor); // 5
317
+
318
+ // meanwhile, some other client submits an edit which gets applied to our string:
319
+ otherSharedString.replaceText(1, 2, "ello");
320
+
321
+ // The local sharedString state will now look like this:
322
+ // cursor: x
323
+ // content: hello world!
324
+ // positions: 0123456789AB (hex)
325
+
326
+ // ... in some view code, retrieve the position of the local reference for rendering:
327
+ const pos = sharedString.localReferencePositionToPosition(cursor); // 8
315
328
  ```
316
329
 
317
330
  Notice that even though another client concurrently edited the string, the local reference representing the cursor is still in the correct location with no further work for the API consumer.
318
331
  The `ReferenceType.SlideOnRemove` parameter changes what happens when the segment that reference is associated with is removed.
319
- `SlideOnRemove` instructs the sequence to attempt to *slide* the reference to the start of the next furthest segment, or if no such segment exists (i.e. the end of the string has been removed), the end of the next nearest one.
332
+ `SlideOnRemove` instructs the sequence to attempt to _slide_ the reference to the start of the next furthest segment, or if no such segment exists (i.e. the end of the string has been removed), the end of the next nearest one.
320
333
 
321
334
  The [webflow](https://github.com/microsoft/FluidFramework/blob/main/examples/data-objects/webflow/src/editor/caret.ts) example demonstrates this idea in more detail.
322
335
 
323
- Unlike segments, it *is* safe to persist local references in auxiliary data structures, such as an undo-redo stack.
336
+ Unlike segments, it _is_ safe to persist local references in auxiliary data structures, such as an undo-redo stack.
324
337
 
325
338
  ## Interval collections
326
339
 
327
- Sequences support creation of *interval collections*, an auxiliary collection of intervals associated with positions in the sequence.
340
+ Sequences support creation of _interval collections_, an auxiliary collection of intervals associated with positions in the sequence.
328
341
  Like segments, intervals support adding arbitrary properties, including handles (references) to other DDSes.
329
342
  The interval collection implementation uses local references, and so benefits from all of the robustness to concurrent editing
330
343
  described in the previous section.
@@ -332,98 +345,266 @@ Unlike local references, operations on interval collections are sent to all clie
332
345
  This makes them suitable for implementing features like comment threads on a text-based documents.
333
346
  The following example illustrates these properties and highlights the major APIs supported by IntervalCollection.
334
347
 
348
+ ```typescript
349
+ // content: hi world!
350
+ // positions: 012345678
351
+
352
+ const comments = sharedString.getIntervalCollection("comments");
353
+ const comment = comments.add(
354
+ 3, // (inclusive)
355
+ 8, // (exclusive): references "world"
356
+ IntervalType.SlideOnRemove,
357
+ {
358
+ creator: "my-user-id",
359
+ handle: myCommentThreadDDS.handle,
360
+ },
361
+ );
362
+ // content: hi world!
363
+ // positions: 012345678
364
+ // comment: [ )
365
+
366
+ // Interval collection supports iterating over all intervals via Symbol.iterator or `.map()`:
367
+ const allIntervalsInCollection = Array.from(comments);
368
+ const allProperties = comments.map((comment) => comment.properties);
369
+ // or iterating over intervals overlapping a region:
370
+ const intervalsOverlappingFirstHalf = comments.findOverlappingIntervals(0, 4);
371
+
372
+ // Interval endpoints are LocalReferencePositions, so all APIs in the above section can be used:
373
+ const startPosition = sharedString.localReferencePositionToPosition(comment.start); // returns 3
374
+ const endPosition = sharedString.localReferencePositionToPosition(comment.end); // returns 8: note this is exclusive!
375
+
376
+ // Intervals can be modified:
377
+ comments.change(comment.getIntervalId(), 0, 1);
378
+ // content: hi world!
379
+ // positions: 012345678
380
+ // comment: [)
381
+
382
+ // their properties can be changed:
383
+ comments.changeProperties(comment.getIntervalId(), { status: "resolved" });
384
+ // comment.properties === { creator: 'my-user-id', handle: <some DDS handle object>, status: "resolved" }
385
+
386
+ // and they can be removed:
387
+ comments.removeIntervalById(comment.getIntervalId());
388
+ ```
389
+
390
+ ### Interval stickiness
391
+
392
+ "Stickiness" refers to the behavior of intervals when text is inserted on either
393
+ side of the interval. A "sticky" interval is one which expands to include text
394
+ inserted directly adjacent to it.
395
+
396
+ A "start sticky" interval is one which expands only to include text inserted to
397
+ the start of it. An "end sticky" interval is the same, but with regard to text
398
+ inserted adjacent to the end.
399
+
400
+ For example, let's look at the string "abc". If we have an interval on the
401
+ character "b", what happens when we insert text on either side of it? In the
402
+ below diagrams, we represent an interval by putting a caret directly underneath
403
+ the characters it contains.
404
+
405
+ #### Example
406
+
407
+ ##### Original string
335
408
 
336
409
  ```typescript
337
- // content: hi world!
338
- // positions: 012345678
410
+ abc
411
+ ^
412
+ ```
339
413
 
340
- const comments = sharedString.getIntervalCollection("comments");
341
- const comment = comments.add(
342
- 3,
343
- 7, // (inclusive range): references "world"
344
- IntervalType.SlideOnRemove,
345
- {
346
- creator: 'my-user-id',
347
- handle: myCommentThreadDDS.handle
348
- }
349
- );
350
- // content: hi world!
351
- // positions: 012345678
352
- // comment: [ ]
414
+ ##### No stickiness
353
415
 
354
- // Interval collection supports iterating over all intervals via Symbol.iterator or `.map()`:
355
- const allIntervalsInCollection = Array.from(comments);
356
- const allProperties = comments.map((comment) => comment.properties);
357
- // or iterating over intervals overlapping a region:
358
- const intervalsOverlappingFirstHalf = comments.findOverlappingIntervals(0, 4);
416
+ ```typescript
417
+ aXbYc
418
+ ^
419
+ ```
359
420
 
360
- // Interval endpoints are LocalReferencePositions, so all APIs in the above section can be used:
361
- const startPosition = sharedString.localReferencePositionToPosition(comment.start);
362
- const endPosition = sharedString.localReferencePositionToPosition(comment.end);
421
+ The interval does not expand to include the newly inserted characters `X` and `Y`.
363
422
 
364
- // Intervals can be modified:
365
- comments.change(comment.getIntervalId(), 0, 1);
366
- // content: hi world!
367
- // positions: 012345678
368
- // comment: []
423
+ ##### Start stickiness
369
424
 
370
- // their properties can be changed:
371
- comments.changeProperties(comment.getIntervalId(), { status: "resolved" });
372
- // comment.properties === { creator: 'my-user-id', handle: <some DDS handle object>, status: "resolved" }
425
+ ```typescript
426
+ aXbYc
427
+ ^^
428
+ ```
429
+
430
+ ##### End stickiness
373
431
 
374
- // and they can be removed:
375
- comments.removeIntervalById(comment.getIntervalId());
432
+ ```typescript
433
+ aXbYc
434
+ ^^
376
435
  ```
377
436
 
437
+ ##### Full stickiness
438
+
439
+ ```typescript
440
+ aXbYc
441
+ ^^^
442
+ ```
443
+
444
+ #### Concrete Implementation
445
+
446
+ The above is a description of the abstract semantics of the concept of stickiness.
447
+ In practice, this is implemented using the concept of "sides."
448
+
449
+ For a given sequence of N characters, there are 2N + 2 positions which can be
450
+ referenced: the position immediately before and after each character, and two
451
+ special endpoint segments denoting the position before and after the start and
452
+ end of the sequence respectively.
453
+
454
+ By placing the endpoints of an interval either before or after a character, it
455
+ is possible to make the endpoints inclusive or exclusive. An exclusive endpoint
456
+ in a given direction implies stickiness in that direction. Whether an endpoint
457
+ is inclusive or exclusive depends on both the Side and if it is the start or the
458
+ end.
459
+
460
+ Given the string "ABCD":
461
+
462
+ ```typescript
463
+ // Refers to "BC". If any content is inserted before B or after C, this
464
+ // interval will include that content
465
+ //
466
+ // Picture:
467
+ // {start} - A[- B - C -]D - {end}
468
+ // {start} - A - B - C - D - {end}
469
+ collection.add(
470
+ { pos: 0, side: Side.After },
471
+ { pos: 3, side: Side.Before },
472
+ IntervalType.SlideOnRemove,
473
+ );
474
+ // Equivalent to specifying the same positions and Side.Before.
475
+ // Refers to "ABC". Content inserted after C will be included in the
476
+ // interval, but content inserted before A will not.
477
+ // {start} -[A - B - C -]D - {end}
478
+ // {start} - A - B - C - D - {end}
479
+ collection.add(0, 3, IntervalType.SlideOnRemove);
480
+ ```
481
+
482
+ In the case of the first interval shown, if text is deleted,
483
+
484
+ ```typescript
485
+ // Delete the character "B"
486
+ string.removeRange(1, 2);
487
+ ```
488
+
489
+ The start point of the interval will slide to the position immediately before
490
+ "C", and the same will be true.
491
+
492
+ ```typescript
493
+ {start} - A[- C -]D - {end}
494
+ ```
495
+
496
+ In this case, text inserted immediately before "C" would be included in the
497
+ interval.
498
+
499
+ ```typescript
500
+ string.insertText(1, "EFG");
501
+ ```
502
+
503
+ With the string now being,
504
+
505
+ ```typescript
506
+ {start} - A[- E - F - G - C -]D - {end}
507
+ ```
508
+
509
+ Note that the endpoint continues to remain with the associated character, except
510
+ when the character is removed. When content containing endpoints is removed,
511
+ `After` endpoints move backward and `Before` endpoints move forward to maintain their
512
+ side value and inclusive/exclusive behavior.
513
+
514
+ <!-- This line ends the content that is copied to the sequences.md README -->
515
+
516
+ ## SharedString
517
+
518
+ SharedString is a specialized data structure for handling collaborative text. It is based on a more general
519
+ Sequence data structure but has additional features that make working with text easier.
520
+
521
+ In addition to text, a SharedString can also contain markers.
522
+ Markers can be used to store metadata at positions within the text, like a reference to an image or Fluid object that should be rendered with the text.
523
+
524
+ Both markers and text are stored as segments in the SharedString.
525
+ Text segments will be split and merged when modifications are made to the SharedString and will therefore have variable length
526
+ matching the length of the text content they contain.
527
+ Marker segments are never split or merged, and always have a length of 1.
528
+
529
+ The length of the SharedString will be the combined length of all the text and marker segments.
530
+ Just like with other sequences, when talking about positions in a SharedString we use the terms near and far.
531
+ The nearest position in a SharedString is 0, and the farthest position is its length.
532
+ When comparing two positions the nearer positions is closer to 0, and the farther position is closer to the length.
533
+
378
534
  ### Intervals vs. markers
379
535
 
380
- Interval endpoints and markers both implement *ReferencePosition* and seem to serve a similar function so it's not obvious how they differ and why you would choose one or the other.
536
+ Interval endpoints and markers both implement _ReferencePosition_ and seem to serve a similar function so it's not obvious how they differ and why you would choose one or the other.
381
537
 
382
538
  Using the interval collection API has two main benefits:
383
539
 
384
540
  1. Efficient spatial querying
541
+
385
542
  - Interval collections support iterating all intervals overlapping the region `[start, end]` in `O(log N) + O(overlap size)` time, where `N` is the total number of intervals in the collection.
386
- This may be critical for applications that display only a small view of the document contents.
387
- On the other hand, using markers to implement intervals would require a linear scan from the start or end of the sequence to determine which intervals overlap.
543
+ This may be critical for applications that display only a small view of the document contents.
544
+ On the other hand, using markers to implement intervals would require a linear scan from the start or end of the sequence to determine which intervals overlap.
388
545
 
389
546
  2. More ergonomic modification APIs
390
547
  - Interval collections natively support a modify operation on the intervals, which allows moving the endpoints of the interval to a different place in the sequence.
391
- This operation is atomic, whereas with markers one would have to submit a delete operation for the existing position and an insert for the new one.
392
- In order to achieve the same atomicity, those operations would need to leverage the `SharedSegmentSequence.groupOperation` API,
393
- which is less user-friendly.
394
- If the ops were submitted using standard insert and delete APIs instead, there would be some potential for data loss if the delete
395
- operation ended up acknowledged by the server but the insert operation did not.
548
+ This operation is atomic, whereas with markers one would have to submit a delete operation for the existing position and an insert for the new one.
549
+ In order to achieve the same atomicity, those operations would need to leverage the `SharedSegmentSequence.groupOperation` API,
550
+ which is less user-friendly.
551
+ If the ops were submitted using standard insert and delete APIs instead, there would be some potential for data loss if the delete
552
+ operation ended up acknowledged by the server but the insert operation did not.
396
553
 
397
- ## SharedString
554
+ ### Attribution
398
555
 
399
- The SharedString is a specialized data structure for handling collaborative text. It is based on a more general
400
- Sequence data structure but has additional features that make working with text easier.
556
+ **Important: Attribution is currently in alpha: expect breaking changes in minor releases as we get feedback on the API shape.**
557
+
558
+ SharedString supports storing information attributing each character position to the user who inserted it and the time at which that insertion happened.
559
+ This functionality is off by default.
560
+ To enable this functionality, first ensure that all clients are created with an attribution policy factory in the loader settings:
401
561
 
402
- In addition to text, a SharedString can also contain markers. Markers can be used to store metadata at positions within
403
- the text, like the details of an image or Fluid object that should be rendered with the text.
562
+ ```typescript
563
+ import { createInsertOnlyAttributionPolicy } from "@fluidframework/merge-tree";
564
+ // Use these options in the IContainerContext used to instantiate your container runtime.
565
+ const options: ILoaderOptions = {
566
+ attribution: {
567
+ policyFactory: createInsertOnlyAttributionPolicy,
568
+ },
569
+ };
570
+ ```
571
+
572
+ This ensures that the client is able to load existing documents containing attribution information,
573
+ and specifies which kinds of operations should be attributed at the SharedString level (currently, only insertions).
574
+ The stored attribution information can be found on the `attribution` field of the SharedString's segments.
404
575
 
405
- Both markers and text are stored as segments in the SharedString. Text segments will be split and merged when
406
- modifications are made to the SharedString and will therefore have variable length matching the length of the text
407
- content they contain. Marker segments are never split or merged, and always have a length of 1.
576
+ Next, enable the `"Fluid.Attribution.EnableOnNewFile"` config flag to start tracking attribution information for new files.
577
+
578
+ ```typescript
579
+ const { segment, offset } = sharedString.getContainingSegment(5);
580
+ const key = segment.attribution.getAtOffset(offset);
581
+ // `key` can be used with an IAttributor to recover user/timestamp info about the insertion of the character at offset 5.
582
+ // See the @fluid-experimental/attributor package for more details.
583
+ ```
408
584
 
409
- The length of the SharedString will be the combined length of all the text and marker segments. Just like with other
410
- sequences, when talking about positions in a SharedString we use the terms near and far. The nearest position in a
411
- SharedString is 0, and the farthest position is its length. When comparing two positions the nearer positions is closer
412
- to 0, and the farther position is closer to the length.
585
+ For further reading on attribution, see the [@fluid-experimental/attributor README](https://github.com/microsoft/FluidFramework/blob/main/packages/framework/attributor/README.md).
586
+
587
+ There are plans to make attribution policies more flexible, for example tracking attribution of property changes separately from segment insertion.
588
+
589
+ <!-- This line begins the content that is copied to the string.md README -->
413
590
 
414
591
  ### Examples
415
592
 
416
- - Rich Text Editor Implementations
417
- - [webflow](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/webflow)
418
- - [flowView](https://github.com/microsoft/FluidFramework/blob/main/examples/data-objects/shared-text/src/client-ui-lib/controls/flowView.ts)
593
+ - Rich Text Editor Implementations
594
+
595
+ - [webflow](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/webflow)
596
+ - [flowView](https://github.com/microsoft/FluidFramework/blob/main/examples/data-objects/shared-text/src/client-ui-lib/controls/flowView.ts)
597
+
598
+ - Integrations with Open Source Rich Text Editors
599
+
600
+ - [prosemirror](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/prosemirror)
601
+ - [smde](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/smde)
419
602
 
420
- - Integrations with Open Source Rich Text Editors
421
- - [prosemirror](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/prosemirror)
422
- - [smde](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/smde)
603
+ - Plain Text Editor Implementations
604
+ - [collaborativeTextArea](https://github.com/microsoft/FluidFramework/blob/main/experimental/framework/react-inputs/src/CollaborativeTextArea.tsx)
605
+ - [collaborativeInput](https://github.com/microsoft/FluidFramework/blob/main/experimental/framework/react-inputs/src/CollaborativeInput.tsx)
423
606
 
424
- - Plain Text Editor Implementations
425
- - [collaborativeTextArea](https://github.com/microsoft/FluidFramework/blob/main/experimental/framework/react-inputs/src/CollaborativeTextArea.tsx)
426
- - [collaborativeInput](https://github.com/microsoft/FluidFramework/blob/main/experimental/framework/react-inputs/src/CollaborativeInput.tsx)
607
+ <!-- This line ends the content that is copied to the string.md README -->
427
608
 
428
- [SharedMap]: https://fluidframework.com/docs/data-structures/map/
429
- [SharedString]: https://github.com/microsoft/FluidFramework/blob/main/packages/dds/sequence/src/sharedString.ts
609
+ [sharedmap]: https://fluidframework.com/docs/data-structures/map/
610
+ [sharedstring]: https://github.com/microsoft/FluidFramework/blob/main/packages/dds/sequence/src/sharedString.ts