@fluidframework/tree 2.12.0 → 2.20.0

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 (496) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/api-report/tree.alpha.api.md +108 -22
  3. package/api-report/tree.beta.api.md +31 -15
  4. package/api-report/tree.legacy.alpha.api.md +31 -15
  5. package/api-report/tree.legacy.public.api.md +31 -15
  6. package/api-report/tree.public.api.md +31 -15
  7. package/assertTagging.config.mjs +14 -0
  8. package/dist/alpha.d.ts +14 -0
  9. package/dist/beta.d.ts +2 -0
  10. package/dist/core/index.d.ts +2 -2
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core/index.js +6 -4
  13. package/dist/core/index.js.map +1 -1
  14. package/dist/core/rebase/index.d.ts +2 -2
  15. package/dist/core/rebase/index.d.ts.map +1 -1
  16. package/dist/core/rebase/index.js +5 -1
  17. package/dist/core/rebase/index.js.map +1 -1
  18. package/dist/core/rebase/types.d.ts +5 -4
  19. package/dist/core/rebase/types.d.ts.map +1 -1
  20. package/dist/core/rebase/types.js +29 -1
  21. package/dist/core/rebase/types.js.map +1 -1
  22. package/dist/core/rebase/utils.d.ts +10 -0
  23. package/dist/core/rebase/utils.d.ts.map +1 -1
  24. package/dist/core/rebase/utils.js +22 -1
  25. package/dist/core/rebase/utils.js.map +1 -1
  26. package/dist/core/tree/delta.d.ts +21 -26
  27. package/dist/core/tree/delta.d.ts.map +1 -1
  28. package/dist/core/tree/delta.js.map +1 -1
  29. package/dist/core/tree/deltaUtil.d.ts +1 -3
  30. package/dist/core/tree/deltaUtil.d.ts.map +1 -1
  31. package/dist/core/tree/deltaUtil.js +2 -14
  32. package/dist/core/tree/deltaUtil.js.map +1 -1
  33. package/dist/core/tree/index.d.ts +1 -1
  34. package/dist/core/tree/index.d.ts.map +1 -1
  35. package/dist/core/tree/index.js +1 -3
  36. package/dist/core/tree/index.js.map +1 -1
  37. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  38. package/dist/core/tree/visitDelta.js +82 -80
  39. package/dist/core/tree/visitDelta.js.map +1 -1
  40. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +10 -0
  41. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  42. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +3 -0
  43. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  44. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  45. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  46. package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
  47. package/dist/feature-libraries/deltaUtils.js +13 -0
  48. package/dist/feature-libraries/deltaUtils.js.map +1 -1
  49. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  50. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  51. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  52. package/dist/feature-libraries/index.d.ts +0 -1
  53. package/dist/feature-libraries/index.d.ts.map +1 -1
  54. package/dist/feature-libraries/index.js +2 -4
  55. package/dist/feature-libraries/index.js.map +1 -1
  56. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +5 -5
  57. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  58. package/dist/feature-libraries/modular-schema/crossFieldQueries.js +2 -3
  59. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  60. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +30 -6
  61. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  62. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  63. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  64. package/dist/feature-libraries/modular-schema/genericFieldKind.js +2 -1
  65. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  66. package/dist/feature-libraries/modular-schema/index.d.ts +2 -2
  67. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  68. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  69. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  70. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  71. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +8 -8
  72. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  73. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +5 -4
  74. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  75. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +186 -216
  76. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  77. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +23 -20
  78. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  79. package/dist/feature-libraries/modular-schema/modularChangeTypes.js +20 -0
  80. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  81. package/dist/feature-libraries/optional-field/optionalField.d.ts +3 -3
  82. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  83. package/dist/feature-libraries/optional-field/optionalField.js +24 -4
  84. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  85. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  86. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  87. package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  88. package/dist/feature-libraries/sequence-field/rebase.js +4 -4
  89. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  90. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  91. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  92. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  93. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  94. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  95. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  96. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  97. package/dist/feature-libraries/sequence-field/utils.d.ts +2 -2
  98. package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  99. package/dist/feature-libraries/sequence-field/utils.js +50 -9
  100. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  101. package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  102. package/dist/feature-libraries/treeCursorUtils.js +4 -1
  103. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  104. package/dist/index.d.ts +27 -3
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +5 -2
  107. package/dist/index.js.map +1 -1
  108. package/dist/legacy.d.ts +2 -0
  109. package/dist/package.json +2 -1
  110. package/dist/packageVersion.d.ts +1 -1
  111. package/dist/packageVersion.js +1 -1
  112. package/dist/packageVersion.js.map +1 -1
  113. package/dist/public.d.ts +2 -0
  114. package/dist/shared-tree/index.d.ts +3 -2
  115. package/dist/shared-tree/index.d.ts.map +1 -1
  116. package/dist/shared-tree/index.js +6 -3
  117. package/dist/shared-tree/index.js.map +1 -1
  118. package/dist/shared-tree/schematizingTreeView.d.ts +10 -1
  119. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  120. package/dist/shared-tree/schematizingTreeView.js +43 -0
  121. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  122. package/dist/shared-tree/sharedTree.d.ts +44 -21
  123. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  124. package/dist/shared-tree/sharedTree.js +41 -35
  125. package/dist/shared-tree/sharedTree.js.map +1 -1
  126. package/dist/shared-tree/transactionTypes.d.ts +105 -0
  127. package/dist/shared-tree/transactionTypes.d.ts.map +1 -0
  128. package/dist/shared-tree/transactionTypes.js +13 -0
  129. package/dist/shared-tree/transactionTypes.js.map +1 -0
  130. package/dist/shared-tree/treeApi.d.ts +1 -25
  131. package/dist/shared-tree/treeApi.d.ts.map +1 -1
  132. package/dist/shared-tree/treeApi.js +4 -8
  133. package/dist/shared-tree/treeApi.js.map +1 -1
  134. package/dist/shared-tree/treeCheckout.d.ts +4 -1
  135. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  136. package/dist/shared-tree/treeCheckout.js +142 -23
  137. package/dist/shared-tree/treeCheckout.js.map +1 -1
  138. package/dist/shared-tree-core/sharedTreeCore.js +1 -1
  139. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  140. package/dist/simple-tree/api/index.d.ts +1 -0
  141. package/dist/simple-tree/api/index.d.ts.map +1 -1
  142. package/dist/simple-tree/api/index.js +3 -1
  143. package/dist/simple-tree/api/index.js.map +1 -1
  144. package/dist/simple-tree/api/jsonSchema.d.ts +6 -0
  145. package/dist/simple-tree/api/jsonSchema.d.ts.map +1 -1
  146. package/dist/simple-tree/api/jsonSchema.js.map +1 -1
  147. package/dist/simple-tree/api/schemaFactory.d.ts +21 -12
  148. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  149. package/dist/simple-tree/api/schemaFactory.js +5 -2
  150. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  151. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +83 -0
  152. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -0
  153. package/dist/simple-tree/api/schemaFactoryAlpha.js +90 -0
  154. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -0
  155. package/dist/simple-tree/api/simpleSchema.d.ts +5 -1
  156. package/dist/simple-tree/api/simpleSchema.d.ts.map +1 -1
  157. package/dist/simple-tree/api/simpleSchema.js.map +1 -1
  158. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +13 -10
  159. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  160. package/dist/simple-tree/api/testRecursiveDomain.d.ts +5 -5
  161. package/dist/simple-tree/api/tree.d.ts +60 -0
  162. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  163. package/dist/simple-tree/api/tree.js.map +1 -1
  164. package/dist/simple-tree/api/treeNodeApi.js +1 -1
  165. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  166. package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
  167. package/dist/simple-tree/api/viewSchemaToSimpleSchema.js +11 -11
  168. package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
  169. package/dist/simple-tree/arrayNode.d.ts +2 -2
  170. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  171. package/dist/simple-tree/arrayNode.js +3 -2
  172. package/dist/simple-tree/arrayNode.js.map +1 -1
  173. package/dist/simple-tree/core/treeNodeSchema.d.ts +10 -6
  174. package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  175. package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
  176. package/dist/simple-tree/index.d.ts +2 -2
  177. package/dist/simple-tree/index.d.ts.map +1 -1
  178. package/dist/simple-tree/index.js +3 -2
  179. package/dist/simple-tree/index.js.map +1 -1
  180. package/dist/simple-tree/leafNodeSchema.d.ts +5 -5
  181. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  182. package/dist/simple-tree/mapNode.d.ts +2 -2
  183. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  184. package/dist/simple-tree/mapNode.js +2 -1
  185. package/dist/simple-tree/mapNode.js.map +1 -1
  186. package/dist/simple-tree/objectNode.d.ts +2 -2
  187. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  188. package/dist/simple-tree/objectNode.js +2 -1
  189. package/dist/simple-tree/objectNode.js.map +1 -1
  190. package/dist/simple-tree/objectNodeTypes.d.ts +2 -2
  191. package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
  192. package/dist/simple-tree/objectNodeTypes.js.map +1 -1
  193. package/dist/simple-tree/schemaTypes.d.ts +47 -1
  194. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  195. package/dist/simple-tree/schemaTypes.js.map +1 -1
  196. package/dist/simple-tree/toMapTree.js +1 -1
  197. package/dist/simple-tree/toMapTree.js.map +1 -1
  198. package/dist/util/bTreeUtils.d.ts +10 -0
  199. package/dist/util/bTreeUtils.d.ts.map +1 -0
  200. package/dist/util/bTreeUtils.js +52 -0
  201. package/dist/util/bTreeUtils.js.map +1 -0
  202. package/dist/util/idAllocator.d.ts +0 -2
  203. package/dist/util/idAllocator.d.ts.map +1 -1
  204. package/dist/util/idAllocator.js +0 -2
  205. package/dist/util/idAllocator.js.map +1 -1
  206. package/dist/util/index.d.ts +3 -2
  207. package/dist/util/index.d.ts.map +1 -1
  208. package/dist/util/index.js +7 -5
  209. package/dist/util/index.js.map +1 -1
  210. package/dist/util/rangeMap.d.ts +95 -43
  211. package/dist/util/rangeMap.d.ts.map +1 -1
  212. package/dist/util/rangeMap.js +202 -148
  213. package/dist/util/rangeMap.js.map +1 -1
  214. package/dist/util/utils.d.ts +26 -2
  215. package/dist/util/utils.d.ts.map +1 -1
  216. package/dist/util/utils.js +17 -2
  217. package/dist/util/utils.js.map +1 -1
  218. package/lib/alpha.d.ts +14 -0
  219. package/lib/beta.d.ts +2 -0
  220. package/lib/core/index.d.ts +2 -2
  221. package/lib/core/index.d.ts.map +1 -1
  222. package/lib/core/index.js +2 -2
  223. package/lib/core/index.js.map +1 -1
  224. package/lib/core/rebase/index.d.ts +2 -2
  225. package/lib/core/rebase/index.d.ts.map +1 -1
  226. package/lib/core/rebase/index.js +2 -2
  227. package/lib/core/rebase/index.js.map +1 -1
  228. package/lib/core/rebase/types.d.ts +5 -4
  229. package/lib/core/rebase/types.d.ts.map +1 -1
  230. package/lib/core/rebase/types.js +26 -1
  231. package/lib/core/rebase/types.js.map +1 -1
  232. package/lib/core/rebase/utils.d.ts +10 -0
  233. package/lib/core/rebase/utils.d.ts.map +1 -1
  234. package/lib/core/rebase/utils.js +20 -0
  235. package/lib/core/rebase/utils.js.map +1 -1
  236. package/lib/core/tree/delta.d.ts +21 -26
  237. package/lib/core/tree/delta.d.ts.map +1 -1
  238. package/lib/core/tree/delta.js.map +1 -1
  239. package/lib/core/tree/deltaUtil.d.ts +1 -3
  240. package/lib/core/tree/deltaUtil.d.ts.map +1 -1
  241. package/lib/core/tree/deltaUtil.js +1 -12
  242. package/lib/core/tree/deltaUtil.js.map +1 -1
  243. package/lib/core/tree/index.d.ts +1 -1
  244. package/lib/core/tree/index.d.ts.map +1 -1
  245. package/lib/core/tree/index.js +1 -1
  246. package/lib/core/tree/index.js.map +1 -1
  247. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  248. package/lib/core/tree/visitDelta.js +82 -80
  249. package/lib/core/tree/visitDelta.js.map +1 -1
  250. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +10 -0
  251. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  252. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +3 -0
  253. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  254. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  255. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  256. package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
  257. package/lib/feature-libraries/deltaUtils.js +13 -0
  258. package/lib/feature-libraries/deltaUtils.js.map +1 -1
  259. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  260. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  261. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  262. package/lib/feature-libraries/index.d.ts +0 -1
  263. package/lib/feature-libraries/index.d.ts.map +1 -1
  264. package/lib/feature-libraries/index.js +0 -1
  265. package/lib/feature-libraries/index.js.map +1 -1
  266. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +5 -5
  267. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  268. package/lib/feature-libraries/modular-schema/crossFieldQueries.js +2 -3
  269. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  270. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +30 -6
  271. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  272. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  273. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  274. package/lib/feature-libraries/modular-schema/genericFieldKind.js +2 -1
  275. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  276. package/lib/feature-libraries/modular-schema/index.d.ts +2 -2
  277. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  278. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  279. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  280. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  281. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  282. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  283. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +5 -4
  284. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  285. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +158 -186
  286. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  287. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +23 -20
  288. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  289. package/lib/feature-libraries/modular-schema/modularChangeTypes.js +18 -1
  290. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  291. package/lib/feature-libraries/optional-field/optionalField.d.ts +3 -3
  292. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  293. package/lib/feature-libraries/optional-field/optionalField.js +24 -4
  294. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  295. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  296. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  297. package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  298. package/lib/feature-libraries/sequence-field/rebase.js +4 -4
  299. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  300. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  301. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  302. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  303. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  304. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  305. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  306. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  307. package/lib/feature-libraries/sequence-field/utils.d.ts +2 -2
  308. package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  309. package/lib/feature-libraries/sequence-field/utils.js +50 -9
  310. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  311. package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  312. package/lib/feature-libraries/treeCursorUtils.js +4 -1
  313. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  314. package/lib/index.d.ts +27 -3
  315. package/lib/index.d.ts.map +1 -1
  316. package/lib/index.js +2 -2
  317. package/lib/index.js.map +1 -1
  318. package/lib/legacy.d.ts +2 -0
  319. package/lib/packageVersion.d.ts +1 -1
  320. package/lib/packageVersion.js +1 -1
  321. package/lib/packageVersion.js.map +1 -1
  322. package/lib/public.d.ts +2 -0
  323. package/lib/shared-tree/index.d.ts +3 -2
  324. package/lib/shared-tree/index.d.ts.map +1 -1
  325. package/lib/shared-tree/index.js +3 -2
  326. package/lib/shared-tree/index.js.map +1 -1
  327. package/lib/shared-tree/schematizingTreeView.d.ts +10 -1
  328. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  329. package/lib/shared-tree/schematizingTreeView.js +46 -3
  330. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  331. package/lib/shared-tree/sharedTree.d.ts +44 -21
  332. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  333. package/lib/shared-tree/sharedTree.js +40 -34
  334. package/lib/shared-tree/sharedTree.js.map +1 -1
  335. package/lib/shared-tree/transactionTypes.d.ts +105 -0
  336. package/lib/shared-tree/transactionTypes.d.ts.map +1 -0
  337. package/lib/shared-tree/transactionTypes.js +10 -0
  338. package/lib/shared-tree/transactionTypes.js.map +1 -0
  339. package/lib/shared-tree/treeApi.d.ts +1 -25
  340. package/lib/shared-tree/treeApi.d.ts.map +1 -1
  341. package/lib/shared-tree/treeApi.js +1 -5
  342. package/lib/shared-tree/treeApi.js.map +1 -1
  343. package/lib/shared-tree/treeCheckout.d.ts +4 -1
  344. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  345. package/lib/shared-tree/treeCheckout.js +143 -24
  346. package/lib/shared-tree/treeCheckout.js.map +1 -1
  347. package/lib/shared-tree-core/sharedTreeCore.js +1 -1
  348. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  349. package/lib/simple-tree/api/index.d.ts +1 -0
  350. package/lib/simple-tree/api/index.d.ts.map +1 -1
  351. package/lib/simple-tree/api/index.js +1 -0
  352. package/lib/simple-tree/api/index.js.map +1 -1
  353. package/lib/simple-tree/api/jsonSchema.d.ts +6 -0
  354. package/lib/simple-tree/api/jsonSchema.d.ts.map +1 -1
  355. package/lib/simple-tree/api/jsonSchema.js.map +1 -1
  356. package/lib/simple-tree/api/schemaFactory.d.ts +21 -12
  357. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  358. package/lib/simple-tree/api/schemaFactory.js +5 -2
  359. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  360. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +83 -0
  361. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -0
  362. package/lib/simple-tree/api/schemaFactoryAlpha.js +86 -0
  363. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -0
  364. package/lib/simple-tree/api/simpleSchema.d.ts +5 -1
  365. package/lib/simple-tree/api/simpleSchema.d.ts.map +1 -1
  366. package/lib/simple-tree/api/simpleSchema.js.map +1 -1
  367. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +14 -11
  368. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  369. package/lib/simple-tree/api/testRecursiveDomain.d.ts +5 -5
  370. package/lib/simple-tree/api/tree.d.ts +60 -0
  371. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  372. package/lib/simple-tree/api/tree.js.map +1 -1
  373. package/lib/simple-tree/api/treeNodeApi.js +1 -1
  374. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  375. package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
  376. package/lib/simple-tree/api/viewSchemaToSimpleSchema.js +12 -12
  377. package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
  378. package/lib/simple-tree/arrayNode.d.ts +2 -2
  379. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  380. package/lib/simple-tree/arrayNode.js +3 -2
  381. package/lib/simple-tree/arrayNode.js.map +1 -1
  382. package/lib/simple-tree/core/treeNodeSchema.d.ts +10 -6
  383. package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  384. package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
  385. package/lib/simple-tree/index.d.ts +2 -2
  386. package/lib/simple-tree/index.d.ts.map +1 -1
  387. package/lib/simple-tree/index.js +1 -1
  388. package/lib/simple-tree/index.js.map +1 -1
  389. package/lib/simple-tree/leafNodeSchema.d.ts +5 -5
  390. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  391. package/lib/simple-tree/mapNode.d.ts +2 -2
  392. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  393. package/lib/simple-tree/mapNode.js +2 -1
  394. package/lib/simple-tree/mapNode.js.map +1 -1
  395. package/lib/simple-tree/objectNode.d.ts +2 -2
  396. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  397. package/lib/simple-tree/objectNode.js +2 -1
  398. package/lib/simple-tree/objectNode.js.map +1 -1
  399. package/lib/simple-tree/objectNodeTypes.d.ts +2 -2
  400. package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
  401. package/lib/simple-tree/objectNodeTypes.js.map +1 -1
  402. package/lib/simple-tree/schemaTypes.d.ts +47 -1
  403. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  404. package/lib/simple-tree/schemaTypes.js.map +1 -1
  405. package/lib/simple-tree/toMapTree.js +1 -1
  406. package/lib/simple-tree/toMapTree.js.map +1 -1
  407. package/lib/util/bTreeUtils.d.ts +10 -0
  408. package/lib/util/bTreeUtils.d.ts.map +1 -0
  409. package/lib/util/bTreeUtils.js +47 -0
  410. package/lib/util/bTreeUtils.js.map +1 -0
  411. package/lib/util/idAllocator.d.ts +0 -2
  412. package/lib/util/idAllocator.d.ts.map +1 -1
  413. package/lib/util/idAllocator.js +0 -2
  414. package/lib/util/idAllocator.js.map +1 -1
  415. package/lib/util/index.d.ts +3 -2
  416. package/lib/util/index.d.ts.map +1 -1
  417. package/lib/util/index.js +3 -2
  418. package/lib/util/index.js.map +1 -1
  419. package/lib/util/rangeMap.d.ts +95 -43
  420. package/lib/util/rangeMap.d.ts.map +1 -1
  421. package/lib/util/rangeMap.js +200 -144
  422. package/lib/util/rangeMap.js.map +1 -1
  423. package/lib/util/utils.d.ts +26 -2
  424. package/lib/util/utils.d.ts.map +1 -1
  425. package/lib/util/utils.js +15 -1
  426. package/lib/util/utils.js.map +1 -1
  427. package/package.json +24 -24
  428. package/src/core/index.ts +5 -2
  429. package/src/core/rebase/index.ts +5 -0
  430. package/src/core/rebase/types.ts +33 -5
  431. package/src/core/rebase/utils.ts +27 -0
  432. package/src/core/tree/delta.ts +21 -26
  433. package/src/core/tree/deltaUtil.ts +1 -16
  434. package/src/core/tree/index.ts +0 -2
  435. package/src/core/tree/visitDelta.ts +108 -97
  436. package/src/feature-libraries/default-schema/defaultEditBuilder.ts +14 -1
  437. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +2 -2
  438. package/src/feature-libraries/deltaUtils.ts +13 -0
  439. package/src/feature-libraries/forest-summary/forestSummarizer.ts +1 -6
  440. package/src/feature-libraries/index.ts +0 -1
  441. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +12 -13
  442. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +33 -9
  443. package/src/feature-libraries/modular-schema/genericFieldKind.ts +6 -4
  444. package/src/feature-libraries/modular-schema/index.ts +3 -0
  445. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +12 -11
  446. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +254 -248
  447. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +51 -26
  448. package/src/feature-libraries/optional-field/optionalField.ts +37 -8
  449. package/src/feature-libraries/sequence-field/moveEffectTable.ts +1 -1
  450. package/src/feature-libraries/sequence-field/rebase.ts +9 -3
  451. package/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts +1 -1
  452. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +1 -1
  453. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +3 -4
  454. package/src/feature-libraries/sequence-field/utils.ts +54 -11
  455. package/src/feature-libraries/treeCursorUtils.ts +6 -1
  456. package/src/index.ts +45 -6
  457. package/src/packageVersion.ts +1 -1
  458. package/src/shared-tree/index.ts +16 -3
  459. package/src/shared-tree/schematizingTreeView.ts +91 -2
  460. package/src/shared-tree/sharedTree.ts +69 -44
  461. package/src/shared-tree/transactionTypes.ts +125 -0
  462. package/src/shared-tree/treeApi.ts +1 -28
  463. package/src/shared-tree/treeCheckout.ts +166 -25
  464. package/src/shared-tree-core/sharedTreeCore.ts +1 -1
  465. package/src/simple-tree/api/index.ts +1 -0
  466. package/src/simple-tree/api/jsonSchema.ts +7 -0
  467. package/src/simple-tree/api/schemaFactory.ts +33 -6
  468. package/src/simple-tree/api/schemaFactoryAlpha.ts +253 -0
  469. package/src/simple-tree/api/simpleSchema.ts +6 -1
  470. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +22 -12
  471. package/src/simple-tree/api/tree.ts +76 -4
  472. package/src/simple-tree/api/treeNodeApi.ts +1 -1
  473. package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +19 -13
  474. package/src/simple-tree/arrayNode.ts +8 -2
  475. package/src/simple-tree/core/treeNodeSchema.ts +51 -7
  476. package/src/simple-tree/index.ts +3 -0
  477. package/src/simple-tree/mapNode.ts +7 -1
  478. package/src/simple-tree/objectNode.ts +7 -1
  479. package/src/simple-tree/objectNodeTypes.ts +4 -1
  480. package/src/simple-tree/schemaTypes.ts +50 -1
  481. package/src/simple-tree/toMapTree.ts +1 -1
  482. package/src/util/bTreeUtils.ts +60 -0
  483. package/src/util/idAllocator.ts +0 -2
  484. package/src/util/index.ts +5 -6
  485. package/src/util/rangeMap.ts +259 -184
  486. package/src/util/utils.ts +57 -4
  487. package/dist/feature-libraries/memoizedIdRangeAllocator.d.ts +0 -38
  488. package/dist/feature-libraries/memoizedIdRangeAllocator.d.ts.map +0 -1
  489. package/dist/feature-libraries/memoizedIdRangeAllocator.js +0 -74
  490. package/dist/feature-libraries/memoizedIdRangeAllocator.js.map +0 -1
  491. package/lib/feature-libraries/memoizedIdRangeAllocator.d.ts +0 -38
  492. package/lib/feature-libraries/memoizedIdRangeAllocator.d.ts.map +0 -1
  493. package/lib/feature-libraries/memoizedIdRangeAllocator.js +0 -71
  494. package/lib/feature-libraries/memoizedIdRangeAllocator.js.map +0 -1
  495. package/lib/package.json +0 -3
  496. package/src/feature-libraries/memoizedIdRangeAllocator.ts +0 -112
@@ -3,232 +3,307 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { oob } from "@fluidframework/core-utils/internal";
6
+ import { assert, oob } from "@fluidframework/core-utils/internal";
7
+ import { BTree } from "@tylerbu/sorted-btree-es6";
7
8
 
8
9
  /**
9
- * A map keyed on integers allowing reading and writing contiguous ranges of integer keys.
10
- *
11
- * TODO: We should avoid the direct exposure of RangeEntry. AB#7414
10
+ * RangeMap represents a mapping from keys of type K to values of type V or undefined.
11
+ * The set of all possible keys is assumed to be fully ordered,
12
+ * and for each key there should be a single next higher key.
13
+ * The values for a range of consecutive keys can be changed or queried in a single operation.
14
+ * The structure of the keys is described by the `offsetKey` and `subtractKeys` functions provided in the constructor.
12
15
  */
13
- export type RangeMap<T> = RangeEntry<T>[];
16
+ export class RangeMap<K, V> {
17
+ private tree: BTree<K, RangeEntry<V>>;
14
18
 
15
- export interface RangeEntry<T> {
16
- start: number;
17
- length: number;
18
- value: T;
19
- }
19
+ /**
20
+ * @param offsetKey - Function which returns a new key which is `offset` keys after `key`.
21
+ * When `offset` is negative, the returned key should come before `key`.
22
+ *
23
+ * @param subtractKeys - Function which returns the difference between `b` and `a`.
24
+ * Offsetting `b` by this difference should return `a`.
25
+ * The difference can be infinite if `a` cannot be reached from `b` by offsetting,
26
+ * but the difference should still be positive if `a` is larger than `b` and negative if smaller.
27
+ */
28
+ public constructor(
29
+ private readonly offsetKey: (key: K, offset: number) => K,
30
+ private readonly subtractKeys: (a: K, b: K) => number,
31
+ ) {
32
+ this.tree = new BTree(undefined, subtractKeys);
33
+ }
20
34
 
21
- /**
22
- * The result of a query about a range of keys.
23
- */
24
- export interface RangeQueryResult<T> {
25
35
  /**
26
- * The value of the first key in the query range.
36
+ * Retrieves all entries from the RangeMap.
27
37
  */
28
- value: T | undefined;
38
+ public entries(): RangeQueryEntry<K, V>[] {
39
+ const entries: RangeQueryEntry<K, V>[] = [];
40
+ for (const [start, entry] of this.tree.entries()) {
41
+ entries.push({ start, length: entry.length, value: entry.value });
42
+ }
43
+
44
+ return entries;
45
+ }
46
+
47
+ public clear(): void {
48
+ this.tree.clear();
49
+ }
29
50
 
30
51
  /**
31
- * The length of the prefix of the query range which have the same value.
32
- * For example, if a RangeMap has the same value for keys 5, 6, and 7,
33
- * a query about the range [5, 10] would give a result with length 3.
52
+ * Retrieves the values for all keys in the query range.
53
+ *
54
+ * @param start - The first key in the range being queried
55
+ * @param length - The length of the query range
56
+ * @returns A list of entries, each describing the value for some subrange of the query.
57
+ * The entries are in the same order as the keys, and there is an entry for every key with a non `undefined` value.
34
58
  */
35
- length: number;
36
- }
59
+ public getAll(start: K, length: number): RangeQueryEntry<K, V>[] {
60
+ const entries = this.getIntersectingEntries(start, length);
61
+ if (entries.length === 0) {
62
+ return entries;
63
+ }
37
64
 
38
- /**
39
- * See comments on `RangeQueryResult`.
40
- */
41
- export function getFromRangeMap<T>(
42
- map: RangeMap<T>,
43
- start: number,
44
- length: number,
45
- ): RangeQueryResult<T> {
46
- for (const range of map) {
47
- if (range.start > start) {
48
- return { value: undefined, length: Math.min(range.start - start, length) };
65
+ const firstEntry = entries[0] ?? oob();
66
+ const lengthBefore = this.subtractKeys(start, firstEntry.start);
67
+ if (lengthBefore > 0) {
68
+ entries[0] = { ...firstEntry, start, length: firstEntry.length - lengthBefore };
49
69
  }
50
70
 
51
- const lastRangeKey = range.start + range.length - 1;
52
- if (lastRangeKey >= start) {
53
- // This range contains `start`.
54
- const overlapLength = lastRangeKey - start + 1;
55
- return { value: range.value, length: Math.min(overlapLength, length) };
71
+ const lastEntry = entries[entries.length - 1] ?? oob();
72
+ const lastEntryKey = this.offsetKey(lastEntry.start, lastEntry.length - 1);
73
+ const lastQueryKey = this.offsetKey(start, length - 1);
74
+ const lengthAfter = this.subtractKeys(lastEntryKey, lastQueryKey);
75
+ if (lengthAfter > 0) {
76
+ entries[entries.length - 1] = { ...lastEntry, length: lastEntry.length - lengthAfter };
56
77
  }
78
+
79
+ return entries;
57
80
  }
58
81
 
59
- // There were no entries intersecting the query range, so the entire query range has undefined value.
60
- return { value: undefined, length };
61
- }
82
+ /**
83
+ * Retrieves the value for some prefix of the query range.
84
+ *
85
+ * @param start - The first key in the query range.
86
+ * @param length - The length of the query range.
87
+ * @returns A RangeQueryResult containing the value associated with `start`,
88
+ * and the number of consecutive keys with that same value (at least 1, at most `length`).
89
+ */
90
+ public getFirst(start: K, length: number): RangeQueryResult<K, V> {
91
+ {
92
+ // We first check for an entry with a key less than or equal to `start`.
93
+ const entry = this.tree.getPairOrNextLower(start);
94
+ if (entry !== undefined) {
95
+ const entryKey = entry[0];
96
+ const { value, length: entryLength } = entry[1];
62
97
 
63
- export function getFirstEntryFromRangeMap<T>(
64
- map: RangeMap<T>,
65
- start: number,
66
- length: number,
67
- ): RangeEntry<T> | undefined {
68
- const lastQueryKey = start + length - 1;
69
- for (const range of map) {
70
- if (range.start > lastQueryKey) {
71
- // We've passed the end of the query range.
72
- break;
98
+ const entryLastKey = this.offsetKey(entryKey, entryLength - 1);
99
+ const overlappingLength = Math.min(this.subtractKeys(entryLastKey, start) + 1, length);
100
+ if (overlappingLength > 0) {
101
+ return { value, start, length: overlappingLength };
102
+ }
103
+ }
73
104
  }
74
105
 
75
- const lastRangeKey = range.start + range.length - 1;
76
- if (lastRangeKey >= start) {
77
- return range;
106
+ {
107
+ // There is no value associated with `start`.
108
+ // Now we need to determine how many of the following keys are also undefined.
109
+ const key = this.tree.nextHigherKey(start);
110
+ if (key !== undefined) {
111
+ const entryKey = key;
112
+
113
+ const lastQueryKey = this.offsetKey(start, length - 1);
114
+ if (this.le(entryKey, lastQueryKey)) {
115
+ return { value: undefined, start, length: this.subtractKeys(entryKey, start) };
116
+ }
117
+ }
118
+
119
+ return { value: undefined, start, length };
78
120
  }
79
121
  }
80
122
 
81
- return undefined;
82
- }
123
+ /**
124
+ * Sets the value for a specified range.
125
+ *
126
+ * @param start - The first key in the range being set.
127
+ * @param length - The length of the range.
128
+ * @param value - The value to associate with the range.
129
+ */
130
+ public set(start: K, length: number, value: V | undefined): void {
131
+ this.delete(start, length);
132
+ if (value !== undefined) {
133
+ this.tree.set(start, { value, length });
134
+ }
135
+ }
83
136
 
84
- /**
85
- * Sets the keys from `start` to `start + length - 1` to `value`.
86
- */
87
- export function setInRangeMap<T>(
88
- map: RangeMap<T>,
89
- start: number,
90
- length: number,
91
- value: T,
92
- ): void {
93
- const end = start + length - 1;
94
- const newEntry: RangeEntry<T> = { start, length, value };
95
-
96
- let iBefore = -1;
97
- let iAfter = map.length;
98
- for (const [i, entry] of map.entries()) {
99
- const entryLastKey = entry.start + entry.length - 1;
100
- if (entryLastKey < start) {
101
- iBefore = i;
102
- } else if (entry.start > end) {
103
- iAfter = i;
104
- break;
137
+ /**
138
+ * Deletes values within a specified range, updating or removing existing entries.
139
+ *
140
+ * 1. If an entry is completely included in the deletion range, the whole entry will be deleted
141
+ * e.g.: map = [[1, 2], [4, 6]], delete range: [3, 6]
142
+ * map becomes [[1, 2]] after deletion
143
+ * (Note: the notation [a, b] represents start = a, end = b for simpler visualization, instead of `b`
144
+ * representing the length)
145
+ *
146
+ * 2. If an entry is partially overlapped with the deletion range, the start or end point will be shifted
147
+ * e.g.: map = [[1, 2], [4, 6]], delete range: [2, 4]
148
+ * map becomes [[1, 1], [5, 6]] after deletion
149
+ *
150
+ * 3. If an entry completely includes the deletion range, the original entry may be split into two.
151
+ * e.g.: map = [[1, 6]], delete range: [2, 4]
152
+ * map becomes [[1, 1], [5, 6]]
153
+ *
154
+ * @param start - The start of the range to delete (inclusive).
155
+ * @param length - The length of the range to delete.
156
+ */
157
+ public delete(start: K, length: number): void {
158
+ const lastDeleteKey = this.offsetKey(start, length - 1);
159
+ for (const { start: key, length: entryLength, value } of this.getIntersectingEntries(
160
+ start,
161
+ length,
162
+ )) {
163
+ this.tree.delete(key);
164
+ const lengthBefore = this.subtractKeys(start, key);
165
+ if (lengthBefore > 0) {
166
+ // A portion of this entry comes before the deletion range, so we reinsert that portion.
167
+ this.tree.set(key, { length: lengthBefore, value });
168
+ }
169
+
170
+ const lastEntryKey = this.offsetKey(key, entryLength - 1);
171
+ const lengthAfter = this.subtractKeys(lastEntryKey, lastDeleteKey);
172
+ if (lengthAfter > 0) {
173
+ // A portion of this entry comes after the deletion range, so we reinsert that portion.
174
+ this.tree.set(this.offsetKey(lastDeleteKey, 1), { length: lengthAfter, value });
175
+ }
105
176
  }
106
177
  }
107
178
 
108
- const numOverlappingEntries = iAfter - iBefore - 1;
109
- if (numOverlappingEntries === 0) {
110
- map.splice(iAfter, 0, newEntry);
111
- return;
179
+ public clone(): RangeMap<K, V> {
180
+ const cloned = new RangeMap<K, V>(this.offsetKey, this.subtractKeys);
181
+ cloned.tree = this.tree.clone();
182
+ return cloned;
183
+ }
184
+
185
+ /**
186
+ * Returns a new map which contains the entries from both input maps.
187
+ */
188
+ public static union<K, V>(a: RangeMap<K, V>, b: RangeMap<K, V>): RangeMap<K, V> {
189
+ assert(
190
+ a.offsetKey === b.offsetKey && a.subtractKeys === b.subtractKeys,
191
+ 0xaae /* Maps should have the same behavior */,
192
+ );
193
+
194
+ const merged = new RangeMap<K, V>(a.offsetKey, a.subtractKeys);
195
+
196
+ // TODO: Is there a good pattern that lets us make `tree` readonly?
197
+ merged.tree = a.tree.clone();
198
+ for (const [key, value] of b.tree.entries()) {
199
+ // TODO: Handle key collisions
200
+ merged.tree.set(key, value);
201
+ }
202
+
203
+ return merged;
112
204
  }
113
205
 
114
- const iFirst = iBefore + 1;
115
- const firstEntry = map[iFirst] ?? oob();
116
- const iLast = iAfter - 1;
117
- const lastEntry = map[iLast] ?? oob();
118
- const lengthBeforeFirst = start - firstEntry.start;
119
- const lastEntryKey = lastEntry.start + lastEntry.length - 1;
120
- const lengthAfterLast = lastEntryKey - end;
121
-
122
- if (lengthBeforeFirst > 0 && lengthAfterLast > 0 && iFirst === iLast) {
123
- // The new entry fits in the middle of an existing entry.
124
- // We replace the existing entry with:
125
- // 1) the portion which comes before `newEntry`
126
- // 2) `newEntry`
127
- // 3) the portion which comes after `newEntry`
128
- map.splice(iFirst, 1, { ...firstEntry, length: lengthBeforeFirst }, newEntry, {
129
- ...lastEntry,
130
- start: end + 1,
131
- length: lengthAfterLast,
132
- });
133
- return;
206
+ private getIntersectingEntries(start: K, length: number): RangeQueryEntry<K, V>[] {
207
+ const entries: RangeQueryEntry<K, V>[] = [];
208
+ const lastQueryKey = this.offsetKey(start, length - 1);
209
+ {
210
+ const entry = this.tree.getPairOrNextLower(start);
211
+ if (entry !== undefined) {
212
+ const key = entry[0];
213
+ const { length: entryLength, value } = entry[1];
214
+ const lastEntryKey = this.offsetKey(key, entryLength - 1);
215
+ if (this.ge(lastEntryKey, start)) {
216
+ entries.push({ start: key, length: entryLength, value });
217
+ }
218
+ }
219
+ }
220
+
221
+ {
222
+ let entry = this.tree.nextHigherPair(start);
223
+ while (entry !== undefined) {
224
+ const key = entry[0];
225
+ if (this.gt(key, lastQueryKey)) {
226
+ break;
227
+ }
228
+
229
+ const { length: entryLength, value } = entry[1];
230
+ const lastEntryKey = this.offsetKey(key, entryLength - 1);
231
+
232
+ entries.push({ start: key, length: entryLength, value });
233
+ entry = this.tree.nextHigherPair(lastEntryKey);
234
+ }
235
+ }
236
+
237
+ return entries;
134
238
  }
135
239
 
136
- if (lengthBeforeFirst > 0) {
137
- map[iFirst] = { ...firstEntry, length: lengthBeforeFirst };
240
+ private gt(a: K, b: K): boolean {
241
+ return this.subtractKeys(a, b) > 0;
242
+ }
138
243
 
139
- // The entry at `iFirst` is no longer overlapping with `newEntry`.
140
- iBefore = iFirst;
244
+ private ge(a: K, b: K): boolean {
245
+ return this.subtractKeys(a, b) >= 0;
141
246
  }
142
247
 
143
- if (lengthAfterLast > 0) {
144
- map[iLast] = {
145
- ...lastEntry,
146
- start: end + 1,
147
- length: lengthAfterLast,
148
- };
248
+ private lt(a: K, b: K): boolean {
249
+ return this.subtractKeys(a, b) < 0;
250
+ }
149
251
 
150
- // The entry at `iLast` is no longer overlapping with `newEntry`.
151
- iAfter = iLast;
252
+ private le(a: K, b: K): boolean {
253
+ return this.subtractKeys(a, b) <= 0;
152
254
  }
255
+ }
153
256
 
154
- const numContainedEntries = iAfter - iBefore - 1;
155
- map.splice(iBefore + 1, numContainedEntries, newEntry);
257
+ /**
258
+ * Represents a contiguous range of values in the RangeMap.
259
+ */
260
+ interface RangeEntry<V> {
261
+ /**
262
+ * The length of the range.
263
+ */
264
+ readonly length: number;
265
+
266
+ /**
267
+ * The value associated with this range.
268
+ */
269
+ readonly value: V;
156
270
  }
157
271
 
158
272
  /**
159
- * Delete the keys from `start` to `start + length - 1`
160
- *
161
- * 1. If an entry is completely included in the deletion range, the whole entry will be deleted
162
- * e.g.: map = [[1, 2], [4, 6]], delete range: [3, 6]
163
- * map becomes [[1, 2]] after deletion
164
- * (Note: the notation [a, b] represents start = a, end = b for simpler visiualization, instead of `b`
165
- * representing the length)
166
- *
167
- * 2. If an entry is partially overlapped with the deletion range, the start or end point will be shifted
168
- * e.g.: map = [[1, 2], [4, 6]], delete range: [2, 4]
169
- * map becomes [[1, 1], [5, 6]] after deletion
170
- *
171
- * 3. If an entry completely includes the deletion range, the original entry may be split into two.
172
- * e.g.: map = [[1, 6]], delete range: [2, 4]
173
- * map becomes [[1, 1], [5, 6]]
174
- *
175
- * TODO: We may find ways to mitigate the code duplication between set and delete, and we need to better
176
- * document the API. AB#7413
273
+ * Describes the result of a range query, including the value and length of the matching prefix.
177
274
  */
178
- export function deleteFromRangeMap<T>(map: RangeMap<T>, start: number, length: number): void {
179
- const end = start + length - 1;
180
-
181
- let iBefore = -1;
182
- let iAfter = map.length;
183
-
184
- for (const [i, entry] of map.entries()) {
185
- const entryLastKey = entry.start + entry.length - 1;
186
- if (entryLastKey < start) {
187
- iBefore = i;
188
- } else if (entry.start > end) {
189
- iAfter = i;
190
- break;
191
- }
192
- }
275
+ export interface RangeQueryResult<K, V> {
276
+ /**
277
+ * The key for the first element in the range.
278
+ */
279
+ readonly start: K;
193
280
 
194
- const numOverlappingEntries = iAfter - iBefore - 1;
281
+ /**
282
+ * The value of the first key in the query range.
283
+ * If no matching range is found, this will be undefined.
284
+ */
285
+ readonly value: V | undefined;
195
286
 
196
- if (numOverlappingEntries === 0) {
197
- // No entry will be removed
198
- return;
199
- }
287
+ /**
288
+ * The length of the prefix of the query range which has the same value.
289
+ * For example, if a RangeMap has the same value for keys 5, 6, and 7,
290
+ * a query about the range [5, 10] would give a result with length 3.
291
+ */
292
+ readonly length: number;
293
+ }
200
294
 
201
- const iFirst = iBefore + 1;
202
- const iLast = iAfter - 1;
203
-
204
- // Update or remove the overlapping entries
205
- for (let i = iFirst; i <= iLast; ++i) {
206
- const entry = map[i] ?? oob();
207
- const entryLastKey = entry.start + entry.length - 1;
208
- let isDirty = false;
209
-
210
- // If the entry lies within the range to be deleted, remove it
211
- if (entry.start >= start && entryLastKey <= end) {
212
- map.splice(i, 1);
213
- } else {
214
- // If the entry partially or completely overlaps with the range to be deleted
215
- if (entry.start < start) {
216
- // Update the endpoint and length of the portion before the range to be deleted
217
- const lengthBefore = start - entry.start;
218
- map[i] = { ...entry, length: lengthBefore };
219
- isDirty = true;
220
- }
295
+ export interface RangeQueryEntry<K, V> extends RangeQueryResult<K, V> {
296
+ readonly value: V;
297
+ }
221
298
 
222
- if (entryLastKey > end) {
223
- // Update the startpoint and length of the portion after the range to be deleted
224
- const newStart = end + 1;
225
- const newLength = entryLastKey - end;
226
- map.splice(isDirty ? i + 1 : i, isDirty ? 0 : 1, {
227
- start: newStart,
228
- length: newLength,
229
- value: entry.value,
230
- });
231
- }
232
- }
233
- }
299
+ export function newIntegerRangeMap<V>(): RangeMap<number, V> {
300
+ return new RangeMap(offsetInteger, subtractIntegers);
301
+ }
302
+
303
+ function offsetInteger(key: number, offset: number): number {
304
+ return key + offset;
305
+ }
306
+
307
+ function subtractIntegers(a: number, b: number): number {
308
+ return a - b;
234
309
  }
package/src/util/utils.ts CHANGED
@@ -16,7 +16,7 @@ export interface MapGetSet<K, V> {
16
16
  }
17
17
 
18
18
  /**
19
- * Make all transitive properties in T readonly
19
+ * Make all transitive properties in `T` readonly
20
20
  */
21
21
  export type RecursiveReadonly<T> = {
22
22
  readonly [P in keyof T]: RecursiveReadonly<T[P]>;
@@ -48,9 +48,16 @@ export function asMutable<T>(readonly: T): Mutable<T> {
48
48
  export const clone = structuredClone;
49
49
 
50
50
  /**
51
- */
52
- export function fail(message: string): never {
53
- throw new Error(message);
51
+ * Throw an error with a constant message.
52
+ * @remarks
53
+ * Works like {@link @fluidframework/core-utils/internal#assert}.
54
+ */
55
+ export function fail(message: string | number): never {
56
+ // Declaring this here aliased to a different name avoids the assert tagging objecting to the usages of `assert` below.
57
+ // Since users of `fail` do the assert message tagging instead, suppressing tagging errors here makes sense.
58
+ const assertNoTag: (condition: boolean, message: string | number) => asserts condition =
59
+ assert;
60
+ assertNoTag(false, message);
54
61
  }
55
62
 
56
63
  /**
@@ -563,3 +570,49 @@ export function defineLazyCachedProperty<
563
570
  });
564
571
  return obj as typeof obj & { [P in K]: V };
565
572
  }
573
+
574
+ /**
575
+ * Copies a given property from one object to another if and only if the property is defined.
576
+ * @param source - The object to copy the property from.
577
+ * If `source` is undefined or does not have the property defined, then this function will do nothing.
578
+ * @param property - The property to copy.
579
+ * @param destination - The object to copy the property to.
580
+ * @remarks This function is useful for copying properties from one object to another while minimizing the presence of `undefined` values.
581
+ * If `property` is not present on `source` - or if `property` is present, but has a value of `undefined` - then this function will not modify `destination`.
582
+ * This is different from doing `destination.foo = source.foo`, which would define a `"foo"` property on `destination` with the value `undefined`.
583
+ *
584
+ * If the type of `source` is known to have `property`, then this function asserts that the type of `destination` has `property` as well after the call.
585
+ *
586
+ * This function first reads the property value (if present) from `source` and then sets it on `destination`, as opposed to e.g. directly copying the property descriptor.
587
+ * @privateRemarks The first overload of this function allows auto-complete to suggest property names from `source`, but by having the second overload we still allow for arbitrary property names.
588
+ */
589
+ export function copyPropertyIfDefined<S extends object, K extends keyof S, D extends object>(
590
+ source: S | undefined,
591
+ property: K,
592
+ destination: D,
593
+ ): asserts destination is K extends keyof S ? D & { [P in K]: S[K] } : D;
594
+ export function copyPropertyIfDefined<
595
+ S extends object,
596
+ K extends string | number | symbol,
597
+ D extends object,
598
+ >(
599
+ source: S | undefined,
600
+ property: K,
601
+ destination: D,
602
+ ): asserts destination is K extends keyof S ? D & { [P in K]: S[K] } : D;
603
+ export function copyPropertyIfDefined<
604
+ S extends object,
605
+ K extends string | number | symbol,
606
+ D extends object,
607
+ >(
608
+ source: S | undefined,
609
+ property: K,
610
+ destination: D,
611
+ ): asserts destination is K extends keyof S ? D & { [P in K]: S[K] } : D {
612
+ if (source !== undefined) {
613
+ const value = (source as { [P in K]?: unknown })[property];
614
+ if (value !== undefined) {
615
+ (destination as { [P in K]: unknown })[property] = value;
616
+ }
617
+ }
618
+ }
@@ -1,38 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import type { ChangesetLocalId, RevisionTag } from "../core/index.js";
6
- /**
7
- * A unique ID allocator that returns the output ID for the same input ID.
8
- */
9
- export interface MemoizedIdRangeAllocator {
10
- /**
11
- * A unique ID allocator that returns the output ID for the same input ID.
12
- *
13
- * "The same" here includes cases where a prior call allocated a range of IDs that partially or fully overlap with the
14
- * current call.
15
- * @param revision - The revision associated with the range of IDs to allocate.
16
- * @param startId - The first ID to allocate.
17
- * @param count - The number of IDs to allocate. Interpreted as 1 if undefined.
18
- */
19
- allocate(revision: RevisionTag | undefined, startId: ChangesetLocalId, count?: number): IdRange[];
20
- /**
21
- * Allocates a new range of IDs.
22
- *
23
- * @param count - The number of IDs to allocate. Interpreted as 1 if undefined.
24
- */
25
- mint(count?: number): ChangesetLocalId;
26
- }
27
- /**
28
- */
29
- export interface IdRange {
30
- readonly first: ChangesetLocalId;
31
- readonly count: number;
32
- }
33
- /**
34
- */
35
- export declare const MemoizedIdRangeAllocator: {
36
- fromNextId(nextId?: number): MemoizedIdRangeAllocator;
37
- };
38
- //# sourceMappingURL=memoizedIdRangeAllocator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memoizedIdRangeAllocator.d.ts","sourceRoot":"","sources":["../../src/feature-libraries/memoizedIdRangeAllocator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAUtE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;;;;;OAQG;IACH,QAAQ,CACP,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,OAAO,EAAE,gBAAgB,EACzB,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,EAAE,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACvC;AAED;GACG;AACH,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED;GACG;AACH,eAAO,MAAM,wBAAwB;wBACjB,MAAM,GAAO,wBAAwB;CA4DxD,CAAC"}