@fluidframework/tree 2.1.0-281041 → 2.1.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 (315) hide show
  1. package/.vscode/Tree.code-workspace +2 -1
  2. package/CHANGELOG.md +38 -0
  3. package/README.md +6 -6
  4. package/api-report/tree.alpha.api.md +1 -1
  5. package/api-report/tree.beta.api.md +1 -1
  6. package/api-report/tree.public.api.md +1 -1
  7. package/dist/core/forest/editableForest.d.ts.map +1 -1
  8. package/dist/core/forest/editableForest.js +4 -2
  9. package/dist/core/forest/editableForest.js.map +1 -1
  10. package/dist/core/tree/anchorSet.d.ts +1 -0
  11. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  12. package/dist/core/tree/anchorSet.js +13 -0
  13. package/dist/core/tree/anchorSet.js.map +1 -1
  14. package/dist/core/tree/detachedFieldIndex.d.ts +48 -11
  15. package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
  16. package/dist/core/tree/detachedFieldIndex.js +144 -20
  17. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  18. package/dist/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
  19. package/dist/core/tree/detachedFieldIndexCodec.js +13 -4
  20. package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
  21. package/dist/core/tree/detachedFieldIndexFormat.d.ts +1 -1
  22. package/dist/core/tree/detachedFieldIndexFormat.d.ts.map +1 -1
  23. package/dist/core/tree/detachedFieldIndexFormat.js.map +1 -1
  24. package/dist/core/tree/detachedFieldIndexTypes.d.ts +39 -4
  25. package/dist/core/tree/detachedFieldIndexTypes.d.ts.map +1 -1
  26. package/dist/core/tree/detachedFieldIndexTypes.js.map +1 -1
  27. package/dist/core/tree/index.d.ts +2 -1
  28. package/dist/core/tree/index.d.ts.map +1 -1
  29. package/dist/core/tree/index.js.map +1 -1
  30. package/dist/core/tree/visitDelta.d.ts +3 -1
  31. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  32. package/dist/core/tree/visitDelta.js +31 -15
  33. package/dist/core/tree/visitDelta.js.map +1 -1
  34. package/dist/core/tree/visitorUtils.d.ts +3 -3
  35. package/dist/core/tree/visitorUtils.d.ts.map +1 -1
  36. package/dist/core/tree/visitorUtils.js +4 -4
  37. package/dist/core/tree/visitorUtils.js.map +1 -1
  38. package/dist/feature-libraries/editableTreeBinder.js +1 -1
  39. package/dist/feature-libraries/editableTreeBinder.js.map +1 -1
  40. package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts +1 -8
  41. package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
  42. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +0 -52
  43. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  44. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -13
  45. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  46. package/dist/feature-libraries/flex-tree/flexTreeTypes.js +0 -2
  47. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  48. package/dist/feature-libraries/flex-tree/index.d.ts +2 -1
  49. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  50. package/dist/feature-libraries/flex-tree/index.js +5 -1
  51. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  52. package/dist/feature-libraries/flex-tree/lazyEntity.d.ts +1 -2
  53. package/dist/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
  54. package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  55. package/dist/feature-libraries/flex-tree/lazyField.d.ts +1 -2
  56. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  57. package/dist/feature-libraries/flex-tree/lazyField.js +10 -18
  58. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  59. package/dist/feature-libraries/flex-tree/lazyNode.d.ts +1 -4
  60. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  61. package/dist/feature-libraries/flex-tree/lazyNode.js +0 -27
  62. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  63. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  64. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -1
  65. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  66. package/dist/feature-libraries/index.d.ts +1 -1
  67. package/dist/feature-libraries/index.d.ts.map +1 -1
  68. package/dist/feature-libraries/index.js +4 -1
  69. package/dist/feature-libraries/index.js.map +1 -1
  70. package/dist/feature-libraries/modular-schema/discrepancies.js +3 -3
  71. package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  72. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +1 -1
  73. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  74. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  75. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +14 -17
  76. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  77. package/dist/feature-libraries/object-forest/objectForest.d.ts +3 -2
  78. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  79. package/dist/feature-libraries/object-forest/objectForest.js +5 -4
  80. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  81. package/dist/packageVersion.d.ts +1 -1
  82. package/dist/packageVersion.d.ts.map +1 -1
  83. package/dist/packageVersion.js +1 -1
  84. package/dist/packageVersion.js.map +1 -1
  85. package/dist/shared-tree/sharedTree.d.ts +5 -1
  86. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  87. package/dist/shared-tree/sharedTree.js +8 -1
  88. package/dist/shared-tree/sharedTree.js.map +1 -1
  89. package/dist/shared-tree/sharedTreeChangeEnricher.js +1 -1
  90. package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  91. package/dist/shared-tree/treeApi.js +1 -1
  92. package/dist/shared-tree/treeApi.js.map +1 -1
  93. package/dist/shared-tree/treeCheckout.d.ts +10 -1
  94. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  95. package/dist/shared-tree/treeCheckout.js +47 -4
  96. package/dist/shared-tree/treeCheckout.js.map +1 -1
  97. package/dist/shared-tree/treeView.d.ts.map +1 -1
  98. package/dist/shared-tree/treeView.js +7 -3
  99. package/dist/shared-tree/treeView.js.map +1 -1
  100. package/dist/shared-tree-core/branch.d.ts +6 -0
  101. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  102. package/dist/shared-tree-core/branch.js +2 -0
  103. package/dist/shared-tree-core/branch.js.map +1 -1
  104. package/dist/shared-tree-core/sharedTreeCore.d.ts +4 -0
  105. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  106. package/dist/shared-tree-core/sharedTreeCore.js +6 -0
  107. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  108. package/dist/simple-tree/arrayNode.js +1 -1
  109. package/dist/simple-tree/arrayNode.js.map +1 -1
  110. package/dist/simple-tree/index.d.ts +3 -3
  111. package/dist/simple-tree/index.d.ts.map +1 -1
  112. package/dist/simple-tree/index.js +2 -1
  113. package/dist/simple-tree/index.js.map +1 -1
  114. package/dist/simple-tree/proxies.d.ts.map +1 -1
  115. package/dist/simple-tree/proxies.js +7 -21
  116. package/dist/simple-tree/proxies.js.map +1 -1
  117. package/dist/simple-tree/proxyBinding.d.ts +4 -0
  118. package/dist/simple-tree/proxyBinding.d.ts.map +1 -1
  119. package/dist/simple-tree/proxyBinding.js +23 -1
  120. package/dist/simple-tree/proxyBinding.js.map +1 -1
  121. package/dist/simple-tree/tree.d.ts.map +1 -1
  122. package/dist/simple-tree/tree.js +1 -1
  123. package/dist/simple-tree/tree.js.map +1 -1
  124. package/dist/simple-tree/treeNodeApi.d.ts +2 -75
  125. package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
  126. package/dist/simple-tree/treeNodeApi.js +7 -15
  127. package/dist/simple-tree/treeNodeApi.js.map +1 -1
  128. package/dist/simple-tree/treeNodeKernel.d.ts +26 -0
  129. package/dist/simple-tree/treeNodeKernel.d.ts.map +1 -0
  130. package/dist/simple-tree/treeNodeKernel.js +83 -0
  131. package/dist/simple-tree/treeNodeKernel.js.map +1 -0
  132. package/dist/simple-tree/types.d.ts +73 -0
  133. package/dist/simple-tree/types.d.ts.map +1 -1
  134. package/dist/simple-tree/types.js +89 -1
  135. package/dist/simple-tree/types.js.map +1 -1
  136. package/dist/util/breakable.js +1 -1
  137. package/dist/util/breakable.js.map +1 -1
  138. package/dist/util/index.d.ts +1 -1
  139. package/dist/util/index.d.ts.map +1 -1
  140. package/dist/util/index.js.map +1 -1
  141. package/lib/core/forest/editableForest.d.ts.map +1 -1
  142. package/lib/core/forest/editableForest.js +4 -2
  143. package/lib/core/forest/editableForest.js.map +1 -1
  144. package/lib/core/tree/anchorSet.d.ts +1 -0
  145. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  146. package/lib/core/tree/anchorSet.js +13 -0
  147. package/lib/core/tree/anchorSet.js.map +1 -1
  148. package/lib/core/tree/detachedFieldIndex.d.ts +48 -11
  149. package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
  150. package/lib/core/tree/detachedFieldIndex.js +145 -21
  151. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  152. package/lib/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
  153. package/lib/core/tree/detachedFieldIndexCodec.js +13 -4
  154. package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
  155. package/lib/core/tree/detachedFieldIndexFormat.d.ts +1 -1
  156. package/lib/core/tree/detachedFieldIndexFormat.d.ts.map +1 -1
  157. package/lib/core/tree/detachedFieldIndexFormat.js.map +1 -1
  158. package/lib/core/tree/detachedFieldIndexTypes.d.ts +39 -4
  159. package/lib/core/tree/detachedFieldIndexTypes.d.ts.map +1 -1
  160. package/lib/core/tree/detachedFieldIndexTypes.js.map +1 -1
  161. package/lib/core/tree/index.d.ts +2 -1
  162. package/lib/core/tree/index.d.ts.map +1 -1
  163. package/lib/core/tree/index.js.map +1 -1
  164. package/lib/core/tree/visitDelta.d.ts +3 -1
  165. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  166. package/lib/core/tree/visitDelta.js +31 -15
  167. package/lib/core/tree/visitDelta.js.map +1 -1
  168. package/lib/core/tree/visitorUtils.d.ts +3 -3
  169. package/lib/core/tree/visitorUtils.d.ts.map +1 -1
  170. package/lib/core/tree/visitorUtils.js +4 -4
  171. package/lib/core/tree/visitorUtils.js.map +1 -1
  172. package/lib/feature-libraries/editableTreeBinder.js +1 -1
  173. package/lib/feature-libraries/editableTreeBinder.js.map +1 -1
  174. package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts +1 -8
  175. package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
  176. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +2 -54
  177. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  178. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -13
  179. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  180. package/lib/feature-libraries/flex-tree/flexTreeTypes.js +0 -2
  181. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  182. package/lib/feature-libraries/flex-tree/index.d.ts +2 -1
  183. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  184. package/lib/feature-libraries/flex-tree/index.js +2 -1
  185. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  186. package/lib/feature-libraries/flex-tree/lazyEntity.d.ts +1 -2
  187. package/lib/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
  188. package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  189. package/lib/feature-libraries/flex-tree/lazyField.d.ts +1 -2
  190. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  191. package/lib/feature-libraries/flex-tree/lazyField.js +12 -20
  192. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  193. package/lib/feature-libraries/flex-tree/lazyNode.d.ts +1 -4
  194. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  195. package/lib/feature-libraries/flex-tree/lazyNode.js +3 -30
  196. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  197. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  198. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -1
  199. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  200. package/lib/feature-libraries/index.d.ts +1 -1
  201. package/lib/feature-libraries/index.d.ts.map +1 -1
  202. package/lib/feature-libraries/index.js +1 -1
  203. package/lib/feature-libraries/index.js.map +1 -1
  204. package/lib/feature-libraries/modular-schema/discrepancies.js +3 -3
  205. package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  206. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +1 -1
  207. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  208. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  209. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +14 -17
  210. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  211. package/lib/feature-libraries/object-forest/objectForest.d.ts +3 -2
  212. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  213. package/lib/feature-libraries/object-forest/objectForest.js +5 -4
  214. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  215. package/lib/packageVersion.d.ts +1 -1
  216. package/lib/packageVersion.d.ts.map +1 -1
  217. package/lib/packageVersion.js +1 -1
  218. package/lib/packageVersion.js.map +1 -1
  219. package/lib/shared-tree/sharedTree.d.ts +5 -1
  220. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  221. package/lib/shared-tree/sharedTree.js +8 -1
  222. package/lib/shared-tree/sharedTree.js.map +1 -1
  223. package/lib/shared-tree/sharedTreeChangeEnricher.js +1 -1
  224. package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  225. package/lib/shared-tree/treeApi.js +1 -1
  226. package/lib/shared-tree/treeApi.js.map +1 -1
  227. package/lib/shared-tree/treeCheckout.d.ts +10 -1
  228. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  229. package/lib/shared-tree/treeCheckout.js +47 -4
  230. package/lib/shared-tree/treeCheckout.js.map +1 -1
  231. package/lib/shared-tree/treeView.d.ts.map +1 -1
  232. package/lib/shared-tree/treeView.js +4 -0
  233. package/lib/shared-tree/treeView.js.map +1 -1
  234. package/lib/shared-tree-core/branch.d.ts +6 -0
  235. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  236. package/lib/shared-tree-core/branch.js +2 -0
  237. package/lib/shared-tree-core/branch.js.map +1 -1
  238. package/lib/shared-tree-core/sharedTreeCore.d.ts +4 -0
  239. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  240. package/lib/shared-tree-core/sharedTreeCore.js +6 -0
  241. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  242. package/lib/simple-tree/arrayNode.js +2 -2
  243. package/lib/simple-tree/arrayNode.js.map +1 -1
  244. package/lib/simple-tree/index.d.ts +3 -3
  245. package/lib/simple-tree/index.d.ts.map +1 -1
  246. package/lib/simple-tree/index.js +1 -1
  247. package/lib/simple-tree/index.js.map +1 -1
  248. package/lib/simple-tree/proxies.d.ts.map +1 -1
  249. package/lib/simple-tree/proxies.js +7 -21
  250. package/lib/simple-tree/proxies.js.map +1 -1
  251. package/lib/simple-tree/proxyBinding.d.ts +4 -0
  252. package/lib/simple-tree/proxyBinding.d.ts.map +1 -1
  253. package/lib/simple-tree/proxyBinding.js +19 -0
  254. package/lib/simple-tree/proxyBinding.js.map +1 -1
  255. package/lib/simple-tree/tree.d.ts.map +1 -1
  256. package/lib/simple-tree/tree.js +1 -1
  257. package/lib/simple-tree/tree.js.map +1 -1
  258. package/lib/simple-tree/treeNodeApi.d.ts +2 -75
  259. package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
  260. package/lib/simple-tree/treeNodeApi.js +9 -17
  261. package/lib/simple-tree/treeNodeApi.js.map +1 -1
  262. package/lib/simple-tree/treeNodeKernel.d.ts +26 -0
  263. package/lib/simple-tree/treeNodeKernel.d.ts.map +1 -0
  264. package/lib/simple-tree/treeNodeKernel.js +79 -0
  265. package/lib/simple-tree/treeNodeKernel.js.map +1 -0
  266. package/lib/simple-tree/types.d.ts +73 -0
  267. package/lib/simple-tree/types.d.ts.map +1 -1
  268. package/lib/simple-tree/types.js +90 -2
  269. package/lib/simple-tree/types.js.map +1 -1
  270. package/lib/util/breakable.js +1 -1
  271. package/lib/util/breakable.js.map +1 -1
  272. package/lib/util/index.d.ts +1 -1
  273. package/lib/util/index.d.ts.map +1 -1
  274. package/lib/util/index.js.map +1 -1
  275. package/package.json +22 -22
  276. package/src/core/forest/editableForest.ts +10 -2
  277. package/src/core/tree/anchorSet.ts +14 -0
  278. package/src/core/tree/detachedFieldIndex.ts +217 -35
  279. package/src/core/tree/detachedFieldIndexCodec.ts +17 -8
  280. package/src/core/tree/detachedFieldIndexFormat.ts +1 -1
  281. package/src/core/tree/detachedFieldIndexTypes.ts +41 -5
  282. package/src/core/tree/index.ts +2 -1
  283. package/src/core/tree/visitDelta.ts +57 -16
  284. package/src/core/tree/visitorUtils.ts +7 -4
  285. package/src/feature-libraries/editableTreeBinder.ts +1 -1
  286. package/src/feature-libraries/flex-map-tree/mapTreeNode.ts +1 -65
  287. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +0 -19
  288. package/src/feature-libraries/flex-tree/index.ts +7 -1
  289. package/src/feature-libraries/flex-tree/lazyEntity.ts +0 -3
  290. package/src/feature-libraries/flex-tree/lazyField.ts +14 -26
  291. package/src/feature-libraries/flex-tree/lazyNode.ts +1 -42
  292. package/src/feature-libraries/forest-summary/forestSummarizer.ts +1 -0
  293. package/src/feature-libraries/index.ts +3 -0
  294. package/src/feature-libraries/modular-schema/discrepancies.ts +3 -3
  295. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +1 -1
  296. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +22 -20
  297. package/src/feature-libraries/object-forest/objectForest.ts +7 -3
  298. package/src/packageVersion.ts +1 -1
  299. package/src/shared-tree/sharedTree.ts +8 -1
  300. package/src/shared-tree/sharedTreeChangeEnricher.ts +1 -1
  301. package/src/shared-tree/treeApi.ts +1 -1
  302. package/src/shared-tree/treeCheckout.ts +56 -5
  303. package/src/shared-tree/treeView.ts +5 -0
  304. package/src/shared-tree-core/branch.ts +9 -0
  305. package/src/shared-tree-core/sharedTreeCore.ts +7 -0
  306. package/src/simple-tree/arrayNode.ts +2 -2
  307. package/src/simple-tree/index.ts +3 -3
  308. package/src/simple-tree/proxies.ts +8 -29
  309. package/src/simple-tree/proxyBinding.ts +23 -0
  310. package/src/simple-tree/tree.ts +4 -1
  311. package/src/simple-tree/treeNodeApi.ts +14 -96
  312. package/src/simple-tree/treeNodeKernel.ts +91 -0
  313. package/src/simple-tree/types.ts +233 -2
  314. package/src/util/breakable.ts +1 -1
  315. package/src/util/index.ts +1 -0
@@ -3,19 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { type ICodecOptions } from "../../codec/index.js";
6
- import { type Brand, type IdAllocator, type JsonCompatibleReadOnly } from "../../util/index.js";
7
- import type { RevisionTagCodec } from "../rebase/index.js";
6
+ import { type IdAllocator, type JsonCompatibleReadOnly } from "../../util/index.js";
7
+ import type { RevisionTag, RevisionTagCodec } from "../rebase/index.js";
8
8
  import type { FieldKey } from "../schema-stored/index.js";
9
9
  import type * as Delta from "./delta.js";
10
- import type { Major } from "./detachedFieldIndexTypes.js";
10
+ import type { ForestRootId, Major } from "./detachedFieldIndexTypes.js";
11
11
  import type { IIdCompressor } from "@fluidframework/id-compressor";
12
- /**
13
- * ID used to create a detached field key for a removed subtree.
14
- *
15
- * TODO: Move to Forest once forests can support multiple roots.
16
- * @internal
17
- */
18
- export type ForestRootId = Brand<number, "tree.ForestRootId">;
19
12
  /**
20
13
  * The tree index records detached field IDs and associates them with a change atom ID.
21
14
  */
@@ -24,9 +17,29 @@ export declare class DetachedFieldIndex {
24
17
  private rootIdAllocator;
25
18
  private readonly revisionTagCodec;
26
19
  private readonly idCompressor;
20
+ /**
21
+ * A mapping from detached node ids to detached fields.
22
+ */
27
23
  private detachedNodeToField;
24
+ /**
25
+ * A map from revisions to all detached fields for which the revision is the latest relevant revision.
26
+ * See {@link DetachedField.latestRelevantRevision}.
27
+ *
28
+ * @remarks
29
+ * undefined revisions are tolerated but any roots not associated with a revision must be disposed manually
30
+ */
31
+ private latestRelevantRevisionToFields;
28
32
  private readonly codec;
29
33
  private readonly options;
34
+ /**
35
+ * The process for loading `DetachedFieldIndex` data from a summary is split into two steps:
36
+ * 1. Call {@link loadData}
37
+ * 2. Call {@link setRevisionsForLoadedData}
38
+ *
39
+ * This flag is only set to `false` after calling `loadData` and is set back to `true` after calling `setRevisionsForLoadedData`.
40
+ * This helps ensure that `setRevisionsForLoadedData` is only called after `loadData` and only called once.
41
+ */
42
+ private isFullyLoaded;
30
43
  /**
31
44
  * @param name - A name for the index, used as a prefix for the generated field keys.
32
45
  * @param rootIdAllocator - An ID allocator used to generate unique field keys.
@@ -35,6 +48,7 @@ export declare class DetachedFieldIndex {
35
48
  clone(): DetachedFieldIndex;
36
49
  entries(): Generator<{
37
50
  root: ForestRootId;
51
+ latestRelevantRevision?: RevisionTag;
38
52
  } & {
39
53
  id: Delta.DetachedNodeId;
40
54
  }>;
@@ -58,15 +72,38 @@ export declare class DetachedFieldIndex {
58
72
  * Fails if no such id is known to the index.
59
73
  */
60
74
  getEntry(id: Delta.DetachedNodeId): ForestRootId;
75
+ /**
76
+ * Returns the detached root IDs for all the trees that were detached or last modified by the given revision.
77
+ */
78
+ getRootsLastTouchedByRevision(revision: RevisionTag): Iterable<ForestRootId>;
79
+ /**
80
+ * Removes the detached roots for all the trees that were detached or last modified by the given revision.
81
+ */
82
+ deleteRootsLastTouchedByRevision(revision: RevisionTag): void;
61
83
  deleteEntry(nodeId: Delta.DetachedNodeId): void;
62
84
  /**
63
85
  * Associates the DetachedNodeId with a field key and creates an entry for it in the index.
86
+ * @param nodeId - The ID of the detached node.
87
+ * @param revision - The revision that last detached the root.
88
+ * See {@link DetachedField.latestRelevantRevision} for details.
89
+ * @param count - The number of entries to create. These entries will have consecutive minor IDs.
90
+ * @returns The atomic ID that the `DetachedFieldIndex` uses to uniquely identify the first root.
64
91
  */
65
- createEntry(nodeId?: Delta.DetachedNodeId, count?: number): ForestRootId;
92
+ createEntry(nodeId?: Delta.DetachedNodeId, revision?: RevisionTag, count?: number): ForestRootId;
93
+ /**
94
+ * Updates the latest revision that is relevant to the provided root
95
+ */
96
+ updateLatestRevision(id: Delta.DetachedNodeId, revision: RevisionTag | undefined): void;
66
97
  encode(): JsonCompatibleReadOnly;
67
98
  /**
68
99
  * Loads the tree index from the given string, this overrides any existing data.
69
100
  */
70
101
  loadData(data: JsonCompatibleReadOnly): void;
102
+ /**
103
+ * Sets the latest relevant revision for any roots that have an undefined latest relevant revision.
104
+ * This occurs when the detached field index is loaded from a summary and can only be called once after
105
+ * the summary has been loaded.
106
+ */
107
+ setRevisionsForLoadedData(latestRevision: RevisionTag): void;
71
108
  }
72
109
  //# sourceMappingURL=detachedFieldIndex.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndex.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,KAAK,aAAa,EAAkC,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACN,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAQ3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAC;AAGzC,OAAO,KAAK,EAA4B,KAAK,EAAS,MAAM,8BAA8B,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D;;GAEG;AACH,qBAAa,kBAAkB;IAW7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAZ9B,OAAO,CAAC,mBAAmB,CAAoD;IAC/E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+C;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC;;;OAGG;gBAEe,IAAI,EAAE,MAAM,EACrB,eAAe,EAAE,WAAW,CAAC,YAAY,CAAC,EACjC,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,aAAa,EAC5C,OAAO,CAAC,EAAE,aAAa;IAMjB,KAAK,IAAI,kBAAkB;IAY1B,OAAO,IAAI,SAAS,CAAC;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC,cAAc,CAAA;KAAE,CAAC;IAcnF;;OAEG;IACI,KAAK,IAAI,IAAI;IAIb,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG,IAAI;IAmBxD;;;OAGG;IACI,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,QAAQ;IAI7C;;;OAGG;IACI,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,cAAc,GAAG,YAAY,GAAG,SAAS;IAItE;;;OAGG;IACI,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,cAAc,GAAG,YAAY;IAMhD,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI;IAKtD;;OAEG;IACI,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,GAAE,MAAU,GAAG,YAAY;IAe3E,MAAM,IAAI,sBAAsB;IAOvC;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,sBAAsB,GAAG,IAAI;CAQnD"}
1
+ {"version":3,"file":"detachedFieldIndex.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,KAAK,aAAa,EAAkC,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAS3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAC;AAGzC,OAAO,KAAK,EAGX,YAAY,EACZ,KAAK,EAEL,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;GAEG;AACH,qBAAa,kBAAkB;IAoC7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAtC9B;;OAEG;IACH,OAAO,CAAC,mBAAmB,CAAqD;IAChF;;;;;;OAMG;IACH,OAAO,CAAC,8BAA8B,CAIxB;IAEd,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+C;IACrE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa,CAAQ;IAE7B;;;OAGG;gBAEe,IAAI,EAAE,MAAM,EACrB,eAAe,EAAE,WAAW,CAAC,YAAY,CAAC,EACjC,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,aAAa,EAC5C,OAAO,CAAC,EAAE,aAAa;IAMjB,KAAK,IAAI,kBAAkB;IAiB1B,OAAO,IAAI,SAAS,CAC3B;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,sBAAsB,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG;QAC9D,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC;KACzB,CACD;IAkBD;;OAEG;IACI,KAAK,IAAI,IAAI;IAKb,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG,IAAI;IAyDxD;;;OAGG;IACI,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,QAAQ;IAI7C;;;OAGG;IACI,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,cAAc,GAAG,YAAY,GAAG,SAAS;IAItE;;;OAGG;IACI,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,cAAc,GAAG,YAAY;IAMvD;;OAEG;IACK,6BAA6B,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC;IAOpF;;OAEG;IACI,gCAAgC,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAiB7D,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI;IAWtD;;;;;;;OAOG;IACI,WAAW,CACjB,MAAM,CAAC,EAAE,KAAK,CAAC,cAAc,EAC7B,QAAQ,CAAC,EAAE,WAAW,EACtB,KAAK,GAAE,MAAU,GACf,YAAY;IAmBf;;OAEG;IACI,oBAAoB,CAC1B,EAAE,EAAE,KAAK,CAAC,cAAc,EACxB,QAAQ,EAAE,WAAW,GAAG,SAAS,GAC/B,IAAI;IAmBA,MAAM,IAAI,sBAAsB;IAOvC;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,sBAAsB,GAAG,IAAI;IAkBnD;;;;OAIG;IACI,yBAAyB,CAAC,cAAc,EAAE,WAAW,GAAG,IAAI;CAkBnE"}
@@ -22,26 +22,50 @@ class DetachedFieldIndex {
22
22
  this.rootIdAllocator = rootIdAllocator;
23
23
  this.revisionTagCodec = revisionTagCodec;
24
24
  this.idCompressor = idCompressor;
25
- // TODO: don't store the field key in the index, it can be derived from the root ID
25
+ /**
26
+ * A mapping from detached node ids to detached fields.
27
+ */
26
28
  this.detachedNodeToField = new Map();
29
+ /**
30
+ * A map from revisions to all detached fields for which the revision is the latest relevant revision.
31
+ * See {@link DetachedField.latestRelevantRevision}.
32
+ *
33
+ * @remarks
34
+ * undefined revisions are tolerated but any roots not associated with a revision must be disposed manually
35
+ */
36
+ this.latestRelevantRevisionToFields = new Map();
37
+ /**
38
+ * The process for loading `DetachedFieldIndex` data from a summary is split into two steps:
39
+ * 1. Call {@link loadData}
40
+ * 2. Call {@link setRevisionsForLoadedData}
41
+ *
42
+ * This flag is only set to `false` after calling `loadData` and is set back to `true` after calling `setRevisionsForLoadedData`.
43
+ * This helps ensure that `setRevisionsForLoadedData` is only called after `loadData` and only called once.
44
+ */
45
+ this.isFullyLoaded = true;
27
46
  this.options = options ?? { jsonValidator: index_js_1.noopValidator };
28
47
  this.codec = (0, detachedFieldIndexCodec_js_1.makeDetachedNodeToFieldCodec)(revisionTagCodec, this.options, idCompressor);
29
48
  }
30
49
  clone() {
31
50
  const clone = new DetachedFieldIndex(this.name, (0, index_js_2.idAllocatorFromMaxId)(this.rootIdAllocator.getMaxId()), this.revisionTagCodec, this.idCompressor, this.options);
32
51
  (0, index_js_2.populateNestedMap)(this.detachedNodeToField, clone.detachedNodeToField, true);
52
+ (0, index_js_2.populateNestedMap)(this.latestRelevantRevisionToFields, clone.latestRelevantRevisionToFields, true);
33
53
  return clone;
34
54
  }
35
55
  *entries() {
36
56
  for (const [major, innerMap] of this.detachedNodeToField) {
37
57
  if (major !== undefined) {
38
- for (const [minor, entry] of innerMap) {
39
- yield { id: { major, minor }, root: entry };
58
+ for (const [minor, { root, latestRelevantRevision }] of innerMap) {
59
+ yield latestRelevantRevision !== undefined
60
+ ? { id: { major, minor }, root, latestRelevantRevision }
61
+ : { id: { major, minor }, root };
40
62
  }
41
63
  }
42
64
  else {
43
- for (const [minor, entry] of innerMap) {
44
- yield { id: { minor }, root: entry };
65
+ for (const [minor, { root, latestRelevantRevision }] of innerMap) {
66
+ yield latestRelevantRevision !== undefined
67
+ ? { id: { minor }, root, latestRelevantRevision }
68
+ : { id: { minor }, root };
45
69
  }
46
70
  }
47
71
  }
@@ -51,19 +75,44 @@ class DetachedFieldIndex {
51
75
  */
52
76
  purge() {
53
77
  this.detachedNodeToField.clear();
78
+ this.latestRelevantRevisionToFields.clear();
54
79
  }
55
80
  updateMajor(current, updated) {
56
- const innerCurrent = this.detachedNodeToField.get(current);
57
- if (innerCurrent !== undefined) {
58
- this.detachedNodeToField.delete(current);
59
- const innerUpdated = this.detachedNodeToField.get(updated);
60
- if (innerUpdated === undefined) {
61
- this.detachedNodeToField.set(updated, innerCurrent);
81
+ // Update latestRelevantRevision information corresponding to `current`
82
+ {
83
+ const inner = this.latestRelevantRevisionToFields.get(current);
84
+ if (inner !== undefined) {
85
+ for (const nodeId of inner.values()) {
86
+ const entry = (0, index_js_2.tryGetFromNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor);
87
+ (0, internal_1.assert)(entry !== undefined, 0x9b8 /* Inconsistent data: missing detached node entry */);
88
+ (0, index_js_2.setInNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor, {
89
+ ...entry,
90
+ latestRelevantRevision: updated,
91
+ });
92
+ }
93
+ this.latestRelevantRevisionToFields.delete(current);
94
+ this.latestRelevantRevisionToFields.set(updated, inner);
62
95
  }
63
- else {
96
+ }
97
+ // Update the major keys corresponding to `current`
98
+ {
99
+ const innerCurrent = this.detachedNodeToField.get(current);
100
+ if (innerCurrent !== undefined) {
101
+ this.detachedNodeToField.delete(current);
102
+ const innerUpdated = this.detachedNodeToField.get(updated);
103
+ if (innerUpdated === undefined) {
104
+ this.detachedNodeToField.set(updated, innerCurrent);
105
+ }
106
+ else {
107
+ for (const [minor, entry] of innerCurrent) {
108
+ (0, internal_1.assert)(innerUpdated.get(minor) === undefined, 0x7a9 /* Collision during index update */);
109
+ innerUpdated.set(minor, entry);
110
+ }
111
+ }
64
112
  for (const [minor, entry] of innerCurrent) {
65
- (0, internal_1.assert)(innerUpdated.get(minor) === undefined, 0x7a9 /* Collision during index update */);
66
- innerUpdated.set(minor, entry);
113
+ const entryInLatest = this.latestRelevantRevisionToFields.get(entry.latestRelevantRevision);
114
+ (0, internal_1.assert)(entryInLatest !== undefined, 0x9b9 /* Inconsistent data: missing node entry in latestRelevantRevision */);
115
+ entryInLatest.set(entry.root, { major: updated, minor });
67
116
  }
68
117
  }
69
118
  }
@@ -80,7 +129,7 @@ class DetachedFieldIndex {
80
129
  * Returns undefined if no such id is known to the index.
81
130
  */
82
131
  tryGetEntry(id) {
83
- return (0, index_js_2.tryGetFromNestedMap)(this.detachedNodeToField, id.major, id.minor);
132
+ return (0, index_js_2.tryGetFromNestedMap)(this.detachedNodeToField, id.major, id.minor)?.root;
84
133
  }
85
134
  /**
86
135
  * Returns the FieldKey associated with the given id.
@@ -91,24 +140,74 @@ class DetachedFieldIndex {
91
140
  (0, internal_1.assert)(key !== undefined, 0x7aa /* Unknown removed node ID */);
92
141
  return key;
93
142
  }
143
+ /**
144
+ * Returns the detached root IDs for all the trees that were detached or last modified by the given revision.
145
+ */
146
+ *getRootsLastTouchedByRevision(revision) {
147
+ const roots = this.latestRelevantRevisionToFields.get(revision);
148
+ if (roots !== undefined) {
149
+ yield* roots.keys();
150
+ }
151
+ }
152
+ /**
153
+ * Removes the detached roots for all the trees that were detached or last modified by the given revision.
154
+ */
155
+ deleteRootsLastTouchedByRevision(revision) {
156
+ const entries = this.latestRelevantRevisionToFields.get(revision);
157
+ if (entries === undefined) {
158
+ return;
159
+ }
160
+ this.latestRelevantRevisionToFields.delete(revision);
161
+ for (const detachedNodeId of entries.values()) {
162
+ const found = (0, index_js_2.deleteFromNestedMap)(this.detachedNodeToField, detachedNodeId.major, detachedNodeId.minor);
163
+ (0, internal_1.assert)(found, 0x9ba /* Unable to delete unknown entry */);
164
+ }
165
+ }
94
166
  deleteEntry(nodeId) {
95
- const found = (0, index_js_2.deleteFromNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor);
96
- (0, internal_1.assert)(found, 0x7ab /* Unable to delete unknown entry */);
167
+ const entry = (0, index_js_2.tryGetFromNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor);
168
+ (0, internal_1.assert)(entry !== undefined, 0x9bb /* Unable to delete unknown entry */);
169
+ (0, index_js_2.deleteFromNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor);
170
+ (0, index_js_2.deleteFromNestedMap)(this.latestRelevantRevisionToFields, entry.latestRelevantRevision, entry.root);
97
171
  }
98
172
  /**
99
173
  * Associates the DetachedNodeId with a field key and creates an entry for it in the index.
174
+ * @param nodeId - The ID of the detached node.
175
+ * @param revision - The revision that last detached the root.
176
+ * See {@link DetachedField.latestRelevantRevision} for details.
177
+ * @param count - The number of entries to create. These entries will have consecutive minor IDs.
178
+ * @returns The atomic ID that the `DetachedFieldIndex` uses to uniquely identify the first root.
100
179
  */
101
- createEntry(nodeId, count = 1) {
180
+ createEntry(nodeId, revision, count = 1) {
102
181
  const root = this.rootIdAllocator.allocate(count);
103
182
  if (nodeId !== undefined) {
104
183
  for (let i = 0; i < count; i++) {
105
184
  (0, internal_1.assert)((0, index_js_2.tryGetFromNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor + i) ===
106
185
  undefined, 0x7ce /* Detached node ID already exists in index */);
107
- (0, index_js_2.setInNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor + i, root + i);
186
+ (0, index_js_2.setInNestedMap)(this.detachedNodeToField, nodeId.major, nodeId.minor + i, {
187
+ root: (0, index_js_2.brand)(root + i),
188
+ latestRelevantRevision: revision,
189
+ });
190
+ (0, index_js_2.setInNestedMap)(this.latestRelevantRevisionToFields, revision, root, nodeId);
108
191
  }
109
192
  }
110
193
  return root;
111
194
  }
195
+ /**
196
+ * Updates the latest revision that is relevant to the provided root
197
+ */
198
+ updateLatestRevision(id, revision) {
199
+ const fieldEntry = (0, index_js_2.tryGetFromNestedMap)(this.detachedNodeToField, id.major, id.minor);
200
+ (0, internal_1.assert)(fieldEntry !== undefined, 0x9bc /* detached node id does not exist in the detached field index */);
201
+ const { root, latestRelevantRevision: previousRevision } = fieldEntry;
202
+ // remove this root from the set of roots for the previous latest revision
203
+ (0, index_js_2.deleteFromNestedMap)(this.latestRelevantRevisionToFields, previousRevision, root);
204
+ // add this root to the set of roots for the new latest revision
205
+ (0, index_js_2.setInNestedMap)(this.latestRelevantRevisionToFields, revision, root, id);
206
+ (0, index_js_2.setInNestedMap)(this.detachedNodeToField, id.major, id.minor, {
207
+ root,
208
+ latestRelevantRevision: revision,
209
+ });
210
+ }
112
211
  encode() {
113
212
  return this.codec.encode({
114
213
  data: this.detachedNodeToField,
@@ -121,7 +220,32 @@ class DetachedFieldIndex {
121
220
  loadData(data) {
122
221
  const detachedFieldIndex = this.codec.decode(data);
123
222
  this.rootIdAllocator = (0, index_js_2.idAllocatorFromMaxId)(detachedFieldIndex.maxId);
124
- this.detachedNodeToField = detachedFieldIndex.data;
223
+ this.detachedNodeToField = new Map();
224
+ this.latestRelevantRevisionToFields = new Map();
225
+ this.isFullyLoaded = false;
226
+ const rootMap = new Map();
227
+ (0, index_js_2.forEachInNestedMap)(detachedFieldIndex.data, ({ root }, major, minor) => {
228
+ rootMap.set(root, { major, minor });
229
+ });
230
+ this.latestRelevantRevisionToFields.set(undefined, rootMap);
231
+ }
232
+ /**
233
+ * Sets the latest relevant revision for any roots that have an undefined latest relevant revision.
234
+ * This occurs when the detached field index is loaded from a summary and can only be called once after
235
+ * the summary has been loaded.
236
+ */
237
+ setRevisionsForLoadedData(latestRevision) {
238
+ (0, internal_1.assert)(!this.isFullyLoaded, 0x9bd /* revisions should only be set once using this function after loading data from a summary */);
239
+ const newDetachedNodeToField = new Map();
240
+ const rootMap = new Map();
241
+ (0, index_js_2.forEachInNestedMap)(this.detachedNodeToField, ({ root }, major, minor) => {
242
+ (0, index_js_2.setInNestedMap)(newDetachedNodeToField, major, minor, { root, latestRevision });
243
+ rootMap.set(root, { major, minor });
244
+ });
245
+ this.detachedNodeToField = newDetachedNodeToField;
246
+ this.latestRelevantRevisionToFields.delete(undefined);
247
+ this.latestRelevantRevisionToFields.set(latestRevision, rootMap);
248
+ this.isFullyLoaded = true;
125
249
  }
126
250
  }
127
251
  exports.DetachedFieldIndex = DetachedFieldIndex;
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndex.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndex.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { type ICodecOptions, type IJsonCodec, noopValidator } from \"../../codec/index.js\";\nimport {\n\ttype Brand,\n\ttype IdAllocator,\n\ttype JsonCompatibleReadOnly,\n\ttype NestedMap,\n\tbrand,\n\tdeleteFromNestedMap,\n\tidAllocatorFromMaxId,\n\tpopulateNestedMap,\n\tsetInNestedMap,\n\ttryGetFromNestedMap,\n} from \"../../util/index.js\";\nimport type { RevisionTagCodec } from \"../rebase/index.js\";\nimport type { FieldKey } from \"../schema-stored/index.js\";\n\nimport type * as Delta from \"./delta.js\";\nimport { makeDetachedNodeToFieldCodec } from \"./detachedFieldIndexCodec.js\";\nimport type { Format } from \"./detachedFieldIndexFormat.js\";\nimport type { DetachedFieldSummaryData, Major, Minor } from \"./detachedFieldIndexTypes.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\n/**\n * ID used to create a detached field key for a removed subtree.\n *\n * TODO: Move to Forest once forests can support multiple roots.\n * @internal\n */\nexport type ForestRootId = Brand<number, \"tree.ForestRootId\">;\n\n/**\n * The tree index records detached field IDs and associates them with a change atom ID.\n */\nexport class DetachedFieldIndex {\n\t// TODO: don't store the field key in the index, it can be derived from the root ID\n\tprivate detachedNodeToField: NestedMap<Major, Minor, ForestRootId> = new Map();\n\tprivate readonly codec: IJsonCodec<DetachedFieldSummaryData, Format>;\n\tprivate readonly options: ICodecOptions;\n\n\t/**\n\t * @param name - A name for the index, used as a prefix for the generated field keys.\n\t * @param rootIdAllocator - An ID allocator used to generate unique field keys.\n\t */\n\tpublic constructor(\n\t\tprivate readonly name: string,\n\t\tprivate rootIdAllocator: IdAllocator<ForestRootId>,\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t\toptions?: ICodecOptions,\n\t) {\n\t\tthis.options = options ?? { jsonValidator: noopValidator };\n\t\tthis.codec = makeDetachedNodeToFieldCodec(revisionTagCodec, this.options, idCompressor);\n\t}\n\n\tpublic clone(): DetachedFieldIndex {\n\t\tconst clone = new DetachedFieldIndex(\n\t\t\tthis.name,\n\t\t\tidAllocatorFromMaxId(this.rootIdAllocator.getMaxId()) as IdAllocator<ForestRootId>,\n\t\t\tthis.revisionTagCodec,\n\t\t\tthis.idCompressor,\n\t\t\tthis.options,\n\t\t);\n\t\tpopulateNestedMap(this.detachedNodeToField, clone.detachedNodeToField, true);\n\t\treturn clone;\n\t}\n\n\tpublic *entries(): Generator<{ root: ForestRootId } & { id: Delta.DetachedNodeId }> {\n\t\tfor (const [major, innerMap] of this.detachedNodeToField) {\n\t\t\tif (major !== undefined) {\n\t\t\t\tfor (const [minor, entry] of innerMap) {\n\t\t\t\t\tyield { id: { major, minor }, root: entry };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const [minor, entry] of innerMap) {\n\t\t\t\t\tyield { id: { minor }, root: entry };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes all entries from the index.\n\t */\n\tpublic purge(): void {\n\t\tthis.detachedNodeToField.clear();\n\t}\n\n\tpublic updateMajor(current: Major, updated: Major): void {\n\t\tconst innerCurrent = this.detachedNodeToField.get(current);\n\t\tif (innerCurrent !== undefined) {\n\t\t\tthis.detachedNodeToField.delete(current);\n\t\t\tconst innerUpdated = this.detachedNodeToField.get(updated);\n\t\t\tif (innerUpdated === undefined) {\n\t\t\t\tthis.detachedNodeToField.set(updated, innerCurrent);\n\t\t\t} else {\n\t\t\t\tfor (const [minor, entry] of innerCurrent) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tinnerUpdated.get(minor) === undefined,\n\t\t\t\t\t\t0x7a9 /* Collision during index update */,\n\t\t\t\t\t);\n\t\t\t\t\tinnerUpdated.set(minor, entry);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns a field key for the given ID.\n\t * This does not save the field key on the index. To do so, call {@link createEntry}.\n\t */\n\tpublic toFieldKey(id: ForestRootId): FieldKey {\n\t\treturn brand(`${this.name}-${id}`);\n\t}\n\n\t/**\n\t * Returns the FieldKey associated with the given id.\n\t * Returns undefined if no such id is known to the index.\n\t */\n\tpublic tryGetEntry(id: Delta.DetachedNodeId): ForestRootId | undefined {\n\t\treturn tryGetFromNestedMap(this.detachedNodeToField, id.major, id.minor);\n\t}\n\n\t/**\n\t * Returns the FieldKey associated with the given id.\n\t * Fails if no such id is known to the index.\n\t */\n\tpublic getEntry(id: Delta.DetachedNodeId): ForestRootId {\n\t\tconst key = this.tryGetEntry(id);\n\t\tassert(key !== undefined, 0x7aa /* Unknown removed node ID */);\n\t\treturn key;\n\t}\n\n\tpublic deleteEntry(nodeId: Delta.DetachedNodeId): void {\n\t\tconst found = deleteFromNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor);\n\t\tassert(found, 0x7ab /* Unable to delete unknown entry */);\n\t}\n\n\t/**\n\t * Associates the DetachedNodeId with a field key and creates an entry for it in the index.\n\t */\n\tpublic createEntry(nodeId?: Delta.DetachedNodeId, count: number = 1): ForestRootId {\n\t\tconst root = this.rootIdAllocator.allocate(count);\n\t\tif (nodeId !== undefined) {\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tassert(\n\t\t\t\t\ttryGetFromNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor + i) ===\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t0x7ce /* Detached node ID already exists in index */,\n\t\t\t\t);\n\t\t\t\tsetInNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor + i, root + i);\n\t\t\t}\n\t\t}\n\t\treturn root;\n\t}\n\n\tpublic encode(): JsonCompatibleReadOnly {\n\t\treturn this.codec.encode({\n\t\t\tdata: this.detachedNodeToField,\n\t\t\tmaxId: this.rootIdAllocator.getMaxId(),\n\t\t}) as JsonCompatibleReadOnly;\n\t}\n\n\t/**\n\t * Loads the tree index from the given string, this overrides any existing data.\n\t */\n\tpublic loadData(data: JsonCompatibleReadOnly): void {\n\t\tconst detachedFieldIndex: DetachedFieldSummaryData = this.codec.decode(data as Format);\n\n\t\tthis.rootIdAllocator = idAllocatorFromMaxId(\n\t\t\tdetachedFieldIndex.maxId,\n\t\t) as IdAllocator<ForestRootId>;\n\t\tthis.detachedNodeToField = detachedFieldIndex.data;\n\t}\n}\n"]}
1
+ {"version":3,"file":"detachedFieldIndex.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndex.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { type ICodecOptions, type IJsonCodec, noopValidator } from \"../../codec/index.js\";\nimport {\n\ttype IdAllocator,\n\ttype JsonCompatibleReadOnly,\n\ttype NestedMap,\n\tbrand,\n\tdeleteFromNestedMap,\n\tforEachInNestedMap,\n\tidAllocatorFromMaxId,\n\tpopulateNestedMap,\n\tsetInNestedMap,\n\ttryGetFromNestedMap,\n} from \"../../util/index.js\";\nimport type { RevisionTag, RevisionTagCodec } from \"../rebase/index.js\";\nimport type { FieldKey } from \"../schema-stored/index.js\";\n\nimport type * as Delta from \"./delta.js\";\nimport { makeDetachedNodeToFieldCodec } from \"./detachedFieldIndexCodec.js\";\nimport type { Format } from \"./detachedFieldIndexFormat.js\";\nimport type {\n\tDetachedField,\n\tDetachedFieldSummaryData,\n\tForestRootId,\n\tMajor,\n\tMinor,\n} from \"./detachedFieldIndexTypes.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\n/**\n * The tree index records detached field IDs and associates them with a change atom ID.\n */\nexport class DetachedFieldIndex {\n\t/**\n\t * A mapping from detached node ids to detached fields.\n\t */\n\tprivate detachedNodeToField: NestedMap<Major, Minor, DetachedField> = new Map();\n\t/**\n\t * A map from revisions to all detached fields for which the revision is the latest relevant revision.\n\t * See {@link DetachedField.latestRelevantRevision}.\n\t *\n\t * @remarks\n\t * undefined revisions are tolerated but any roots not associated with a revision must be disposed manually\n\t */\n\tprivate latestRelevantRevisionToFields: NestedMap<\n\t\tRevisionTag | undefined,\n\t\tForestRootId,\n\t\tDelta.DetachedNodeId\n\t> = new Map();\n\n\tprivate readonly codec: IJsonCodec<DetachedFieldSummaryData, Format>;\n\tprivate readonly options: ICodecOptions;\n\n\t/**\n\t * The process for loading `DetachedFieldIndex` data from a summary is split into two steps:\n\t * 1. Call {@link loadData}\n\t * 2. Call {@link setRevisionsForLoadedData}\n\t *\n\t * This flag is only set to `false` after calling `loadData` and is set back to `true` after calling `setRevisionsForLoadedData`.\n\t * This helps ensure that `setRevisionsForLoadedData` is only called after `loadData` and only called once.\n\t */\n\tprivate isFullyLoaded = true;\n\n\t/**\n\t * @param name - A name for the index, used as a prefix for the generated field keys.\n\t * @param rootIdAllocator - An ID allocator used to generate unique field keys.\n\t */\n\tpublic constructor(\n\t\tprivate readonly name: string,\n\t\tprivate rootIdAllocator: IdAllocator<ForestRootId>,\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t\toptions?: ICodecOptions,\n\t) {\n\t\tthis.options = options ?? { jsonValidator: noopValidator };\n\t\tthis.codec = makeDetachedNodeToFieldCodec(revisionTagCodec, this.options, idCompressor);\n\t}\n\n\tpublic clone(): DetachedFieldIndex {\n\t\tconst clone = new DetachedFieldIndex(\n\t\t\tthis.name,\n\t\t\tidAllocatorFromMaxId(this.rootIdAllocator.getMaxId()) as IdAllocator<ForestRootId>,\n\t\t\tthis.revisionTagCodec,\n\t\t\tthis.idCompressor,\n\t\t\tthis.options,\n\t\t);\n\t\tpopulateNestedMap(this.detachedNodeToField, clone.detachedNodeToField, true);\n\t\tpopulateNestedMap(\n\t\t\tthis.latestRelevantRevisionToFields,\n\t\t\tclone.latestRelevantRevisionToFields,\n\t\t\ttrue,\n\t\t);\n\t\treturn clone;\n\t}\n\n\tpublic *entries(): Generator<\n\t\t{ root: ForestRootId; latestRelevantRevision?: RevisionTag } & {\n\t\t\tid: Delta.DetachedNodeId;\n\t\t}\n\t> {\n\t\tfor (const [major, innerMap] of this.detachedNodeToField) {\n\t\t\tif (major !== undefined) {\n\t\t\t\tfor (const [minor, { root, latestRelevantRevision }] of innerMap) {\n\t\t\t\t\tyield latestRelevantRevision !== undefined\n\t\t\t\t\t\t? { id: { major, minor }, root, latestRelevantRevision }\n\t\t\t\t\t\t: { id: { major, minor }, root };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const [minor, { root, latestRelevantRevision }] of innerMap) {\n\t\t\t\t\tyield latestRelevantRevision !== undefined\n\t\t\t\t\t\t? { id: { minor }, root, latestRelevantRevision }\n\t\t\t\t\t\t: { id: { minor }, root };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes all entries from the index.\n\t */\n\tpublic purge(): void {\n\t\tthis.detachedNodeToField.clear();\n\t\tthis.latestRelevantRevisionToFields.clear();\n\t}\n\n\tpublic updateMajor(current: Major, updated: Major): void {\n\t\t// Update latestRelevantRevision information corresponding to `current`\n\t\t{\n\t\t\tconst inner = this.latestRelevantRevisionToFields.get(current);\n\t\t\tif (inner !== undefined) {\n\t\t\t\tfor (const nodeId of inner.values()) {\n\t\t\t\t\tconst entry = tryGetFromNestedMap(\n\t\t\t\t\t\tthis.detachedNodeToField,\n\t\t\t\t\t\tnodeId.major,\n\t\t\t\t\t\tnodeId.minor,\n\t\t\t\t\t);\n\t\t\t\t\tassert(\n\t\t\t\t\t\tentry !== undefined,\n\t\t\t\t\t\t0x9b8 /* Inconsistent data: missing detached node entry */,\n\t\t\t\t\t);\n\t\t\t\t\tsetInNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor, {\n\t\t\t\t\t\t...entry,\n\t\t\t\t\t\tlatestRelevantRevision: updated,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.latestRelevantRevisionToFields.delete(current);\n\t\t\t\tthis.latestRelevantRevisionToFields.set(updated, inner);\n\t\t\t}\n\t\t}\n\n\t\t// Update the major keys corresponding to `current`\n\t\t{\n\t\t\tconst innerCurrent = this.detachedNodeToField.get(current);\n\t\t\tif (innerCurrent !== undefined) {\n\t\t\t\tthis.detachedNodeToField.delete(current);\n\t\t\t\tconst innerUpdated = this.detachedNodeToField.get(updated);\n\t\t\t\tif (innerUpdated === undefined) {\n\t\t\t\t\tthis.detachedNodeToField.set(updated, innerCurrent);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const [minor, entry] of innerCurrent) {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\tinnerUpdated.get(minor) === undefined,\n\t\t\t\t\t\t\t0x7a9 /* Collision during index update */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tinnerUpdated.set(minor, entry);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const [minor, entry] of innerCurrent) {\n\t\t\t\t\tconst entryInLatest = this.latestRelevantRevisionToFields.get(\n\t\t\t\t\t\tentry.latestRelevantRevision,\n\t\t\t\t\t);\n\t\t\t\t\tassert(\n\t\t\t\t\t\tentryInLatest !== undefined,\n\t\t\t\t\t\t0x9b9 /* Inconsistent data: missing node entry in latestRelevantRevision */,\n\t\t\t\t\t);\n\t\t\t\t\tentryInLatest.set(entry.root, { major: updated, minor });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns a field key for the given ID.\n\t * This does not save the field key on the index. To do so, call {@link createEntry}.\n\t */\n\tpublic toFieldKey(id: ForestRootId): FieldKey {\n\t\treturn brand(`${this.name}-${id}`);\n\t}\n\n\t/**\n\t * Returns the FieldKey associated with the given id.\n\t * Returns undefined if no such id is known to the index.\n\t */\n\tpublic tryGetEntry(id: Delta.DetachedNodeId): ForestRootId | undefined {\n\t\treturn tryGetFromNestedMap(this.detachedNodeToField, id.major, id.minor)?.root;\n\t}\n\n\t/**\n\t * Returns the FieldKey associated with the given id.\n\t * Fails if no such id is known to the index.\n\t */\n\tpublic getEntry(id: Delta.DetachedNodeId): ForestRootId {\n\t\tconst key = this.tryGetEntry(id);\n\t\tassert(key !== undefined, 0x7aa /* Unknown removed node ID */);\n\t\treturn key;\n\t}\n\n\t/**\n\t * Returns the detached root IDs for all the trees that were detached or last modified by the given revision.\n\t */\n\tpublic *getRootsLastTouchedByRevision(revision: RevisionTag): Iterable<ForestRootId> {\n\t\tconst roots = this.latestRelevantRevisionToFields.get(revision);\n\t\tif (roots !== undefined) {\n\t\t\tyield* roots.keys();\n\t\t}\n\t}\n\n\t/**\n\t * Removes the detached roots for all the trees that were detached or last modified by the given revision.\n\t */\n\tpublic deleteRootsLastTouchedByRevision(revision: RevisionTag): void {\n\t\tconst entries = this.latestRelevantRevisionToFields.get(revision);\n\t\tif (entries === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.latestRelevantRevisionToFields.delete(revision);\n\t\tfor (const detachedNodeId of entries.values()) {\n\t\t\tconst found = deleteFromNestedMap(\n\t\t\t\tthis.detachedNodeToField,\n\t\t\t\tdetachedNodeId.major,\n\t\t\t\tdetachedNodeId.minor,\n\t\t\t);\n\t\t\tassert(found, 0x9ba /* Unable to delete unknown entry */);\n\t\t}\n\t}\n\n\tpublic deleteEntry(nodeId: Delta.DetachedNodeId): void {\n\t\tconst entry = tryGetFromNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor);\n\t\tassert(entry !== undefined, 0x9bb /* Unable to delete unknown entry */);\n\t\tdeleteFromNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor);\n\t\tdeleteFromNestedMap(\n\t\t\tthis.latestRelevantRevisionToFields,\n\t\t\tentry.latestRelevantRevision,\n\t\t\tentry.root,\n\t\t);\n\t}\n\n\t/**\n\t * Associates the DetachedNodeId with a field key and creates an entry for it in the index.\n\t * @param nodeId - The ID of the detached node.\n\t * @param revision - The revision that last detached the root.\n\t * See {@link DetachedField.latestRelevantRevision} for details.\n\t * @param count - The number of entries to create. These entries will have consecutive minor IDs.\n\t * @returns The atomic ID that the `DetachedFieldIndex` uses to uniquely identify the first root.\n\t */\n\tpublic createEntry(\n\t\tnodeId?: Delta.DetachedNodeId,\n\t\trevision?: RevisionTag,\n\t\tcount: number = 1,\n\t): ForestRootId {\n\t\tconst root = this.rootIdAllocator.allocate(count);\n\t\tif (nodeId !== undefined) {\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tassert(\n\t\t\t\t\ttryGetFromNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor + i) ===\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t0x7ce /* Detached node ID already exists in index */,\n\t\t\t\t);\n\t\t\t\tsetInNestedMap(this.detachedNodeToField, nodeId.major, nodeId.minor + i, {\n\t\t\t\t\troot: brand<ForestRootId>(root + i),\n\t\t\t\t\tlatestRelevantRevision: revision,\n\t\t\t\t});\n\t\t\t\tsetInNestedMap(this.latestRelevantRevisionToFields, revision, root, nodeId);\n\t\t\t}\n\t\t}\n\t\treturn root;\n\t}\n\n\t/**\n\t * Updates the latest revision that is relevant to the provided root\n\t */\n\tpublic updateLatestRevision(\n\t\tid: Delta.DetachedNodeId,\n\t\trevision: RevisionTag | undefined,\n\t): void {\n\t\tconst fieldEntry = tryGetFromNestedMap(this.detachedNodeToField, id.major, id.minor);\n\t\tassert(\n\t\t\tfieldEntry !== undefined,\n\t\t\t0x9bc /* detached node id does not exist in the detached field index */,\n\t\t);\n\t\tconst { root, latestRelevantRevision: previousRevision } = fieldEntry;\n\n\t\t// remove this root from the set of roots for the previous latest revision\n\t\tdeleteFromNestedMap(this.latestRelevantRevisionToFields, previousRevision, root);\n\n\t\t// add this root to the set of roots for the new latest revision\n\t\tsetInNestedMap(this.latestRelevantRevisionToFields, revision, root, id);\n\t\tsetInNestedMap(this.detachedNodeToField, id.major, id.minor, {\n\t\t\troot,\n\t\t\tlatestRelevantRevision: revision,\n\t\t});\n\t}\n\n\tpublic encode(): JsonCompatibleReadOnly {\n\t\treturn this.codec.encode({\n\t\t\tdata: this.detachedNodeToField,\n\t\t\tmaxId: this.rootIdAllocator.getMaxId(),\n\t\t});\n\t}\n\n\t/**\n\t * Loads the tree index from the given string, this overrides any existing data.\n\t */\n\tpublic loadData(data: JsonCompatibleReadOnly): void {\n\t\tconst detachedFieldIndex: DetachedFieldSummaryData = this.codec.decode(data as Format);\n\n\t\tthis.rootIdAllocator = idAllocatorFromMaxId(\n\t\t\tdetachedFieldIndex.maxId,\n\t\t) as IdAllocator<ForestRootId>;\n\n\t\tthis.detachedNodeToField = new Map();\n\t\tthis.latestRelevantRevisionToFields = new Map();\n\t\tthis.isFullyLoaded = false;\n\t\tconst rootMap = new Map<ForestRootId, Delta.DetachedNodeId>();\n\t\tforEachInNestedMap(detachedFieldIndex.data, ({ root }, major, minor) => {\n\t\t\trootMap.set(root, { major, minor });\n\t\t});\n\n\t\tthis.latestRelevantRevisionToFields.set(undefined, rootMap);\n\t}\n\n\t/**\n\t * Sets the latest relevant revision for any roots that have an undefined latest relevant revision.\n\t * This occurs when the detached field index is loaded from a summary and can only be called once after\n\t * the summary has been loaded.\n\t */\n\tpublic setRevisionsForLoadedData(latestRevision: RevisionTag): void {\n\t\tassert(\n\t\t\t!this.isFullyLoaded,\n\t\t\t0x9bd /* revisions should only be set once using this function after loading data from a summary */,\n\t\t);\n\n\t\tconst newDetachedNodeToField = new Map();\n\t\tconst rootMap = new Map();\n\t\tforEachInNestedMap(this.detachedNodeToField, ({ root }, major, minor) => {\n\t\t\tsetInNestedMap(newDetachedNodeToField, major, minor, { root, latestRevision });\n\t\t\trootMap.set(root, { major, minor });\n\t\t});\n\n\t\tthis.detachedNodeToField = newDetachedNodeToField;\n\t\tthis.latestRelevantRevisionToFields.delete(undefined);\n\t\tthis.latestRelevantRevisionToFields.set(latestRevision, rootMap);\n\t\tthis.isFullyLoaded = true;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexCodec.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAsB,gBAAgB,EAAe,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EAEN,MAAM,EAGN,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,wBAAwB,EAAS,MAAM,8BAA8B,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA6CnE,wBAAgB,4BAA4B,CAC3C,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,aAAa,GACzB,UAAU,CAAC,wBAAwB,EAAE,MAAM,CAAC,CA2C9C"}
1
+ {"version":3,"file":"detachedFieldIndexCodec.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAsB,gBAAgB,EAAe,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAEN,MAAM,EAGN,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAEX,wBAAwB,EAExB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA6CnE,wBAAgB,4BAA4B,CAC3C,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,aAAa,GACzB,UAAU,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAiD9C"}
@@ -49,7 +49,10 @@ function makeDetachedNodeToFieldCodec(revisionTagCodec, options, idCompressor) {
49
49
  const rootsForRevisions = [];
50
50
  for (const [major, innerMap] of data.data) {
51
51
  const encodedRevision = majorCodec.encode(major);
52
- const rootRanges = [...innerMap];
52
+ const rootRanges = [];
53
+ for (const [minor, detachedField] of innerMap) {
54
+ rootRanges.push([minor, detachedField.root]);
55
+ }
53
56
  if (rootRanges.length === 1) {
54
57
  const rootsForRevision = [
55
58
  encodedRevision,
@@ -73,9 +76,15 @@ function makeDetachedNodeToFieldCodec(revisionTagCodec, options, idCompressor) {
73
76
  decode: (parsed) => {
74
77
  const map = new Map();
75
78
  for (const rootsForRevision of parsed.data) {
76
- const innerMap = new Map(rootsForRevision.length === 2
77
- ? rootsForRevision[1]
78
- : [[rootsForRevision[1], rootsForRevision[2]]]);
79
+ const innerMap = new Map();
80
+ if (rootsForRevision.length === 2) {
81
+ for (const [minor, root] of rootsForRevision[1]) {
82
+ innerMap.set(minor, { root });
83
+ }
84
+ }
85
+ else {
86
+ innerMap.set(rootsForRevision[1], { root: rootsForRevision[2] });
87
+ }
79
88
  map.set(majorCodec.decode(rootsForRevision[0]), innerMap);
80
89
  }
81
90
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexCodec.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype ICodecOptions,\n\ttype IJsonCodec,\n\tmakeVersionedValidatedCodec,\n} from \"../../codec/index.js\";\nimport type { EncodedRevisionTag, RevisionTagCodec, RevisionTag } from \"../rebase/index.js\";\n\nimport type { ForestRootId } from \"./detachedFieldIndex.js\";\nimport {\n\ttype EncodedRootsForRevision,\n\tFormat,\n\ttype RootRanges,\n\tversion,\n} from \"./detachedFieldIndexFormat.js\";\nimport type { DetachedFieldSummaryData, Major } from \"./detachedFieldIndexTypes.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nclass MajorCodec implements IJsonCodec<Major> {\n\tpublic constructor(\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly options: ICodecOptions,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic encode(major: Major): EncodedRevisionTag {\n\t\tassert(major !== undefined, 0x88e /* Unexpected undefined revision */);\n\t\tconst id = this.revisionTagCodec.encode(major);\n\t\t/**\n\t\t * Preface: this codec is only used at summarization time (not for ops).\n\t\t * Note that the decode path must provide a session id in which to interpret the revision tag.\n\t\t * The revision associated with a detached root generally comes from the session which detaches that subtree,\n\t\t * which isn't generally the local session (nor is it available at decode time with the layering of the tree\n\t\t * package), despite decode using the local session id.\n\t\t *\n\t\t * This is made OK by enforcing that all ids on encode/decode are non-local, since local ids won't be interpretable\n\t\t * at decode time.\n\t\t * This assert is valid because the revision for an acked edit will have already been finalized, and a revision\n\t\t * for a local-only edit will be finalizable at summarization time (local edits can only occur on a summarizing client\n\t\t * if they're created while detached, and local ids made while detached are finalized before generating the attach summary).\n\t\t */\n\t\tassert(\n\t\t\tid === \"root\" || id >= 0,\n\t\t\t0x88f /* Expected final id on encode of detached field index revision */,\n\t\t);\n\t\treturn id;\n\t}\n\n\tpublic decode(major: EncodedRevisionTag): RevisionTag {\n\t\tassert(\n\t\t\tmajor === \"root\" || major >= 0,\n\t\t\t0x890 /* Expected final id on decode of detached field index revision */,\n\t\t);\n\t\treturn this.revisionTagCodec.decode(major, {\n\t\t\toriginatorId: this.revisionTagCodec.localSessionId,\n\t\t\tidCompressor: this.idCompressor,\n\t\t\trevision: undefined,\n\t\t});\n\t}\n}\n\nexport function makeDetachedNodeToFieldCodec(\n\trevisionTagCodec: RevisionTagCodec,\n\toptions: ICodecOptions,\n\tidCompressor: IIdCompressor,\n): IJsonCodec<DetachedFieldSummaryData, Format> {\n\tconst majorCodec = new MajorCodec(revisionTagCodec, options, idCompressor);\n\treturn makeVersionedValidatedCodec(options, new Set([version]), Format, {\n\t\tencode: (data: DetachedFieldSummaryData): Format => {\n\t\t\tconst rootsForRevisions: EncodedRootsForRevision[] = [];\n\t\t\tfor (const [major, innerMap] of data.data) {\n\t\t\t\tconst encodedRevision = majorCodec.encode(major);\n\t\t\t\tconst rootRanges: RootRanges = [...innerMap];\n\t\t\t\tif (rootRanges.length === 1) {\n\t\t\t\t\tconst rootsForRevision: EncodedRootsForRevision = [\n\t\t\t\t\t\tencodedRevision,\n\t\t\t\t\t\trootRanges[0][0],\n\t\t\t\t\t\trootRanges[0][1],\n\t\t\t\t\t];\n\t\t\t\t\trootsForRevisions.push(rootsForRevision);\n\t\t\t\t} else {\n\t\t\t\t\tconst rootsForRevision: EncodedRootsForRevision = [encodedRevision, rootRanges];\n\t\t\t\t\trootsForRevisions.push(rootsForRevision);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst encoded: Format = {\n\t\t\t\tversion,\n\t\t\t\tdata: rootsForRevisions,\n\t\t\t\tmaxId: data.maxId,\n\t\t\t};\n\t\t\treturn encoded;\n\t\t},\n\t\tdecode: (parsed: Format): DetachedFieldSummaryData => {\n\t\t\tconst map = new Map();\n\t\t\tfor (const rootsForRevision of parsed.data) {\n\t\t\t\tconst innerMap = new Map<number, ForestRootId>(\n\t\t\t\t\trootsForRevision.length === 2\n\t\t\t\t\t\t? rootsForRevision[1]\n\t\t\t\t\t\t: [[rootsForRevision[1], rootsForRevision[2]]],\n\t\t\t\t);\n\t\t\t\tmap.set(majorCodec.decode(rootsForRevision[0]), innerMap);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: map,\n\t\t\t\tmaxId: parsed.maxId,\n\t\t\t};\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"detachedFieldIndexCodec.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype ICodecOptions,\n\ttype IJsonCodec,\n\tmakeVersionedValidatedCodec,\n} from \"../../codec/index.js\";\nimport type { EncodedRevisionTag, RevisionTagCodec, RevisionTag } from \"../rebase/index.js\";\n\nimport {\n\ttype EncodedRootsForRevision,\n\tFormat,\n\ttype RootRanges,\n\tversion,\n} from \"./detachedFieldIndexFormat.js\";\nimport type {\n\tDetachedField,\n\tDetachedFieldSummaryData,\n\tMajor,\n} from \"./detachedFieldIndexTypes.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nclass MajorCodec implements IJsonCodec<Major> {\n\tpublic constructor(\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly options: ICodecOptions,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic encode(major: Major): EncodedRevisionTag {\n\t\tassert(major !== undefined, 0x88e /* Unexpected undefined revision */);\n\t\tconst id = this.revisionTagCodec.encode(major);\n\t\t/**\n\t\t * Preface: this codec is only used at summarization time (not for ops).\n\t\t * Note that the decode path must provide a session id in which to interpret the revision tag.\n\t\t * The revision associated with a detached root generally comes from the session which detaches that subtree,\n\t\t * which isn't generally the local session (nor is it available at decode time with the layering of the tree\n\t\t * package), despite decode using the local session id.\n\t\t *\n\t\t * This is made OK by enforcing that all ids on encode/decode are non-local, since local ids won't be interpretable\n\t\t * at decode time.\n\t\t * This assert is valid because the revision for an acked edit will have already been finalized, and a revision\n\t\t * for a local-only edit will be finalizable at summarization time (local edits can only occur on a summarizing client\n\t\t * if they're created while detached, and local ids made while detached are finalized before generating the attach summary).\n\t\t */\n\t\tassert(\n\t\t\tid === \"root\" || id >= 0,\n\t\t\t0x88f /* Expected final id on encode of detached field index revision */,\n\t\t);\n\t\treturn id;\n\t}\n\n\tpublic decode(major: EncodedRevisionTag): RevisionTag {\n\t\tassert(\n\t\t\tmajor === \"root\" || major >= 0,\n\t\t\t0x890 /* Expected final id on decode of detached field index revision */,\n\t\t);\n\t\treturn this.revisionTagCodec.decode(major, {\n\t\t\toriginatorId: this.revisionTagCodec.localSessionId,\n\t\t\tidCompressor: this.idCompressor,\n\t\t\trevision: undefined,\n\t\t});\n\t}\n}\n\nexport function makeDetachedNodeToFieldCodec(\n\trevisionTagCodec: RevisionTagCodec,\n\toptions: ICodecOptions,\n\tidCompressor: IIdCompressor,\n): IJsonCodec<DetachedFieldSummaryData, Format> {\n\tconst majorCodec = new MajorCodec(revisionTagCodec, options, idCompressor);\n\treturn makeVersionedValidatedCodec(options, new Set([version]), Format, {\n\t\tencode: (data: DetachedFieldSummaryData): Format => {\n\t\t\tconst rootsForRevisions: EncodedRootsForRevision[] = [];\n\t\t\tfor (const [major, innerMap] of data.data) {\n\t\t\t\tconst encodedRevision = majorCodec.encode(major);\n\t\t\t\tconst rootRanges: RootRanges = [];\n\t\t\t\tfor (const [minor, detachedField] of innerMap) {\n\t\t\t\t\trootRanges.push([minor, detachedField.root]);\n\t\t\t\t}\n\t\t\t\tif (rootRanges.length === 1) {\n\t\t\t\t\tconst rootsForRevision: EncodedRootsForRevision = [\n\t\t\t\t\t\tencodedRevision,\n\t\t\t\t\t\trootRanges[0][0],\n\t\t\t\t\t\trootRanges[0][1],\n\t\t\t\t\t];\n\t\t\t\t\trootsForRevisions.push(rootsForRevision);\n\t\t\t\t} else {\n\t\t\t\t\tconst rootsForRevision: EncodedRootsForRevision = [encodedRevision, rootRanges];\n\t\t\t\t\trootsForRevisions.push(rootsForRevision);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst encoded: Format = {\n\t\t\t\tversion,\n\t\t\t\tdata: rootsForRevisions,\n\t\t\t\tmaxId: data.maxId,\n\t\t\t};\n\t\t\treturn encoded;\n\t\t},\n\t\tdecode: (parsed: Format): DetachedFieldSummaryData => {\n\t\t\tconst map = new Map();\n\t\t\tfor (const rootsForRevision of parsed.data) {\n\t\t\t\tconst innerMap = new Map<number, DetachedField>();\n\t\t\t\tif (rootsForRevision.length === 2) {\n\t\t\t\t\tfor (const [minor, root] of rootsForRevision[1]) {\n\t\t\t\t\t\tinnerMap.set(minor, { root });\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tinnerMap.set(rootsForRevision[1], { root: rootsForRevision[2] });\n\t\t\t\t}\n\t\t\t\tmap.set(majorCodec.decode(rootsForRevision[0]), innerMap);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: map,\n\t\t\t\tmaxId: parsed.maxId,\n\t\t\t};\n\t\t},\n\t});\n}\n"]}
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { type Static } from "@sinclair/typebox";
6
- import type { ForestRootId } from "./detachedFieldIndex.js";
6
+ import type { ForestRootId } from "./detachedFieldIndexTypes.js";
7
7
  export declare const version = 1;
8
8
  /**
9
9
  * The ID of a detached node. Is not globally unique on.
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexFormat.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexFormat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAKtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,eAAO,MAAM,OAAO,IAAM,CAAC;AAE3B;;;GAGG;AACH,eAAO,MAAM,QAAQ,qCAAiC,CAAC;AAQvD;;;;GAIG;AACH,eAAO,MAAM,SAAS,8HAKpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AAEjD,eAAO,MAAM,UAAU,kKAAwB,CAAC;AAChD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,uBAAuB,80BAKlC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE7E,eAAO,MAAM,MAAM;;;;EAOlB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"detachedFieldIndexFormat.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexFormat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAKtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,eAAO,MAAM,OAAO,IAAM,CAAC;AAE3B;;;GAGG;AACH,eAAO,MAAM,QAAQ,qCAAiC,CAAC;AAQvD;;;;GAIG;AACH,eAAO,MAAM,SAAS,8HAKpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AAEjD,eAAO,MAAM,UAAU,kKAAwB,CAAC;AAChD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,uBAAuB,80BAKlC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE7E,eAAO,MAAM,MAAM;;;;EAOlB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexFormat.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexFormat.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+CAAsD;AAEtD,kDAAwD;AACxD,iDAAuD;AAI1C,QAAA,OAAO,GAAG,GAAG,CAAC;AAE3B;;;GAGG;AACU,QAAA,QAAQ,GAAG,cAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,kBAAkB,GAAG,IAAA,4BAAiB,EAAe,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAE3F;;;;GAIG;AACU,QAAA,SAAS,GAAG,cAAI,CAAC,KAAK,CAAC;IACnC,iCAAiC;IACjC,gBAAQ;IACR,6BAA6B;IAC7B,kBAAkB;CAClB,CAAC,CAAC;AAGU,QAAA,UAAU,GAAG,cAAI,CAAC,KAAK,CAAC,iBAAS,CAAC,CAAC;AAGhD;;GAEG;AACU,QAAA,uBAAuB,GAAG,cAAI,CAAC,KAAK,CAAC;IACjD,yEAAyE;IACzE,cAAI,CAAC,KAAK,CAAC,CAAC,4BAAiB,EAAE,kBAAU,CAAC,CAAC;IAC3C,mEAAmE;IACnE,cAAI,CAAC,KAAK,CAAC,CAAC,4BAAiB,EAAE,gBAAQ,EAAE,kBAAkB,CAAC,CAAC;CAC7D,CAAC,CAAC;AAGU,QAAA,MAAM,GAAG,cAAI,CAAC,MAAM,CAChC;IACC,OAAO,EAAE,cAAI,CAAC,OAAO,CAAC,eAAO,CAAC;IAC9B,IAAI,EAAE,cAAI,CAAC,KAAK,CAAC,+BAAuB,CAAC;IACzC,KAAK,EAAE,kBAAkB;CACzB,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type Static, Type } from \"@sinclair/typebox\";\n\nimport { brandedNumberType } from \"../../util/index.js\";\nimport { RevisionTagSchema } from \"../rebase/index.js\";\n\nimport type { ForestRootId } from \"./detachedFieldIndex.js\";\n\nexport const version = 1.0;\n\n/**\n * The ID of a detached node. Is not globally unique on.\n * A `RevisionTag` + `DetachId` pair is globally unique and eventually consistent across clients.\n */\nexport const DetachId = Type.Number({ multipleOf: 1 });\n\n/**\n * The ID of a root node in the forest associated with the owning checkout. Is unique for that forest.\n * Is not consistent across clients.\n */\nconst ForestRootIdSchema = brandedNumberType<ForestRootId>({ minimum: -1, multipleOf: 1 });\n\n/**\n * A mapping from a range of the detached node IDs the corresponding range root IDs.\n * The detached node IDs need to be qualified with a revision (stored in the containing `EncodedRootsForRevision`).\n * Note: the length of the range (currently always 1) can be looked up in the forest.\n */\nexport const RootRange = Type.Tuple([\n\t// ID for the first detached node\n\tDetachId,\n\t// ID for the first root node\n\tForestRootIdSchema,\n]);\nexport type RootRange = Static<typeof RootRange>;\n\nexport const RootRanges = Type.Array(RootRange);\nexport type RootRanges = Static<typeof RootRanges>;\n\n/**\n * For all the roots detached in a revision, represents a mapping from the detached node ID to corresponding root ID.\n */\nexport const EncodedRootsForRevision = Type.Union([\n\t// Used to represent a revision in which more than one node were detached\n\tType.Tuple([RevisionTagSchema, RootRanges]),\n\t// Used to represent a revision in which a single node was detached\n\tType.Tuple([RevisionTagSchema, DetachId, ForestRootIdSchema]),\n]);\nexport type EncodedRootsForRevision = Static<typeof EncodedRootsForRevision>;\n\nexport const Format = Type.Object(\n\t{\n\t\tversion: Type.Literal(version),\n\t\tdata: Type.Array(EncodedRootsForRevision),\n\t\tmaxId: ForestRootIdSchema,\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type Format = Static<typeof Format>;\n"]}
1
+ {"version":3,"file":"detachedFieldIndexFormat.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexFormat.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+CAAsD;AAEtD,kDAAwD;AACxD,iDAAuD;AAI1C,QAAA,OAAO,GAAG,GAAG,CAAC;AAE3B;;;GAGG;AACU,QAAA,QAAQ,GAAG,cAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,kBAAkB,GAAG,IAAA,4BAAiB,EAAe,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAE3F;;;;GAIG;AACU,QAAA,SAAS,GAAG,cAAI,CAAC,KAAK,CAAC;IACnC,iCAAiC;IACjC,gBAAQ;IACR,6BAA6B;IAC7B,kBAAkB;CAClB,CAAC,CAAC;AAGU,QAAA,UAAU,GAAG,cAAI,CAAC,KAAK,CAAC,iBAAS,CAAC,CAAC;AAGhD;;GAEG;AACU,QAAA,uBAAuB,GAAG,cAAI,CAAC,KAAK,CAAC;IACjD,yEAAyE;IACzE,cAAI,CAAC,KAAK,CAAC,CAAC,4BAAiB,EAAE,kBAAU,CAAC,CAAC;IAC3C,mEAAmE;IACnE,cAAI,CAAC,KAAK,CAAC,CAAC,4BAAiB,EAAE,gBAAQ,EAAE,kBAAkB,CAAC,CAAC;CAC7D,CAAC,CAAC;AAGU,QAAA,MAAM,GAAG,cAAI,CAAC,MAAM,CAChC;IACC,OAAO,EAAE,cAAI,CAAC,OAAO,CAAC,eAAO,CAAC;IAC9B,IAAI,EAAE,cAAI,CAAC,KAAK,CAAC,+BAAuB,CAAC;IACzC,KAAK,EAAE,kBAAkB;CACzB,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type Static, Type } from \"@sinclair/typebox\";\n\nimport { brandedNumberType } from \"../../util/index.js\";\nimport { RevisionTagSchema } from \"../rebase/index.js\";\n\nimport type { ForestRootId } from \"./detachedFieldIndexTypes.js\";\n\nexport const version = 1.0;\n\n/**\n * The ID of a detached node. Is not globally unique on.\n * A `RevisionTag` + `DetachId` pair is globally unique and eventually consistent across clients.\n */\nexport const DetachId = Type.Number({ multipleOf: 1 });\n\n/**\n * The ID of a root node in the forest associated with the owning checkout. Is unique for that forest.\n * Is not consistent across clients.\n */\nconst ForestRootIdSchema = brandedNumberType<ForestRootId>({ minimum: -1, multipleOf: 1 });\n\n/**\n * A mapping from a range of the detached node IDs the corresponding range root IDs.\n * The detached node IDs need to be qualified with a revision (stored in the containing `EncodedRootsForRevision`).\n * Note: the length of the range (currently always 1) can be looked up in the forest.\n */\nexport const RootRange = Type.Tuple([\n\t// ID for the first detached node\n\tDetachId,\n\t// ID for the first root node\n\tForestRootIdSchema,\n]);\nexport type RootRange = Static<typeof RootRange>;\n\nexport const RootRanges = Type.Array(RootRange);\nexport type RootRanges = Static<typeof RootRanges>;\n\n/**\n * For all the roots detached in a revision, represents a mapping from the detached node ID to corresponding root ID.\n */\nexport const EncodedRootsForRevision = Type.Union([\n\t// Used to represent a revision in which more than one node were detached\n\tType.Tuple([RevisionTagSchema, RootRanges]),\n\t// Used to represent a revision in which a single node was detached\n\tType.Tuple([RevisionTagSchema, DetachId, ForestRootIdSchema]),\n]);\nexport type EncodedRootsForRevision = Static<typeof EncodedRootsForRevision>;\n\nexport const Format = Type.Object(\n\t{\n\t\tversion: Type.Literal(version),\n\t\tdata: Type.Array(EncodedRootsForRevision),\n\t\tmaxId: ForestRootIdSchema,\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type Format = Static<typeof Format>;\n"]}
@@ -2,13 +2,48 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import type { NestedMap } from "../../util/index.js";
5
+ import type { Brand, ReadonlyNestedMap } from "../../util/index.js";
6
6
  import type { RevisionTag } from "../rebase/index.js";
7
- import type { ForestRootId } from "./detachedFieldIndex.js";
8
7
  export type Major = RevisionTag | undefined;
9
8
  export type Minor = number;
10
9
  export interface DetachedFieldSummaryData {
11
- data: NestedMap<Major, Minor, ForestRootId>;
12
- maxId: ForestRootId;
10
+ readonly data: ReadonlyNestedMap<Major, Minor, DetachedField>;
11
+ readonly maxId: ForestRootId;
12
+ }
13
+ /**
14
+ * ID used to create a detached field key for a removed subtree.
15
+ *
16
+ * TODO: Move to Forest once forests can support multiple roots.
17
+ * @internal
18
+ */
19
+ export type ForestRootId = Brand<number, "tree.ForestRootId">;
20
+ /**
21
+ * A field that is detached from the main document tree.
22
+ */
23
+ export interface DetachedField {
24
+ /**
25
+ * The atomic ID that the `DetachedFieldIndex` uses to uniquely identify the first (and only) root in the field.
26
+ * This ID is scoped to the specific `DetachedFieldIndex` from witch this object was retrieved.
27
+ *
28
+ * The current implementation only supports a single root per field.
29
+ * This will be changed in the future for performance reasons.
30
+ */
31
+ readonly root: ForestRootId;
32
+ /**
33
+ * The revision that last detached the root node or modified its contents (including its descendant's contents).
34
+ *
35
+ * Once this revision is trimmed from the ancestry on which a `TreeCheckout` is moored,
36
+ * the contents of the associated subtree (and the very fact of its past existence) can be erased.
37
+ *
38
+ * @remarks
39
+ * undefined revisions are tolerated but any roots not associated with a revision must be disposed manually.
40
+ * Current usages of undefined are:
41
+ * - When loading a {@link DetachedFieldIndex} from a snapshot,
42
+ * until {@link DetachedFieldIndex.setRevisionsForLoadedData} is called.
43
+ * - When applying a rollback changeset.
44
+ * This only occurs within the context of {@link DefaultResubmitMachine} whose repair data is GC-ed when its
45
+ * `DetachedField` and `Forest` are GC-ed.
46
+ */
47
+ readonly latestRelevantRevision?: RevisionTag;
13
48
  }
14
49
  //# sourceMappingURL=detachedFieldIndexTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexTypes.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,SAAS,CAAC;AAC5C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC;AAE3B,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC5C,KAAK,EAAE,YAAY,CAAC;CACpB"}
1
+ {"version":3,"file":"detachedFieldIndexTypes.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,SAAS,CAAC;AAC5C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC;AAE3B,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,WAAW,CAAC;CAC9C"}
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexTypes.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { NestedMap } from \"../../util/index.js\";\nimport type { RevisionTag } from \"../rebase/index.js\";\n\nimport type { ForestRootId } from \"./detachedFieldIndex.js\";\n\nexport type Major = RevisionTag | undefined;\nexport type Minor = number;\n\nexport interface DetachedFieldSummaryData {\n\tdata: NestedMap<Major, Minor, ForestRootId>;\n\tmaxId: ForestRootId;\n}\n"]}
1
+ {"version":3,"file":"detachedFieldIndexTypes.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { Brand, ReadonlyNestedMap } from \"../../util/index.js\";\nimport type { RevisionTag } from \"../rebase/index.js\";\n\nexport type Major = RevisionTag | undefined;\nexport type Minor = number;\n\nexport interface DetachedFieldSummaryData {\n\treadonly data: ReadonlyNestedMap<Major, Minor, DetachedField>;\n\treadonly maxId: ForestRootId;\n}\n\n/**\n * ID used to create a detached field key for a removed subtree.\n *\n * TODO: Move to Forest once forests can support multiple roots.\n * @internal\n */\nexport type ForestRootId = Brand<number, \"tree.ForestRootId\">;\n\n/**\n * A field that is detached from the main document tree.\n */\nexport interface DetachedField {\n\t/**\n\t * The atomic ID that the `DetachedFieldIndex` uses to uniquely identify the first (and only) root in the field.\n\t * This ID is scoped to the specific `DetachedFieldIndex` from witch this object was retrieved.\n\t *\n\t * The current implementation only supports a single root per field.\n\t * This will be changed in the future for performance reasons.\n\t */\n\treadonly root: ForestRootId;\n\t/**\n\t * The revision that last detached the root node or modified its contents (including its descendant's contents).\n\t *\n\t * Once this revision is trimmed from the ancestry on which a `TreeCheckout` is moored,\n\t * the contents of the associated subtree (and the very fact of its past existence) can be erased.\n\t *\n\t * @remarks\n\t * undefined revisions are tolerated but any roots not associated with a revision must be disposed manually.\n\t * Current usages of undefined are:\n\t * - When loading a {@link DetachedFieldIndex} from a snapshot,\n\t * until {@link DetachedFieldIndex.setRevisionsForLoadedData} is called.\n\t * - When applying a rollback changeset.\n\t * This only occurs within the context of {@link DefaultResubmitMachine} whose repair data is GC-ed when its\n\t * `DetachedField` and `Forest` are GC-ed.\n\t */\n\treadonly latestRelevantRevision?: RevisionTag;\n}\n"]}
@@ -15,5 +15,6 @@ export { type AnnouncedVisitor, announceDelta, applyDelta, combineVisitors, make
15
15
  export type { PathVisitor } from "./visitPath.js";
16
16
  export { SparseNode, getDescendant } from "./sparseTree.js";
17
17
  export { deltaForRootInitialization, emptyFieldChanges, isEmptyFieldChanges, makeDetachedNodeId, offsetDetachId, emptyDelta, } from "./deltaUtil.js";
18
- export { DetachedFieldIndex, type ForestRootId } from "./detachedFieldIndex.js";
18
+ export { DetachedFieldIndex } from "./detachedFieldIndex.js";
19
+ export { type ForestRootId } from "./detachedFieldIndexTypes.js";
19
20
  //# sourceMappingURL=index.d.ts.map