@fluidframework/tree 2.61.0 → 2.62.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 (388) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/api-report/tree.alpha.api.md +26 -21
  3. package/api-report/tree.beta.api.md +15 -0
  4. package/api-report/tree.legacy.beta.api.md +18 -0
  5. package/dist/alpha.d.ts +8 -8
  6. package/dist/api.d.ts +17 -0
  7. package/dist/api.d.ts.map +1 -0
  8. package/dist/api.js +24 -0
  9. package/dist/api.js.map +1 -0
  10. package/dist/beta.d.ts +5 -0
  11. package/dist/codec/codec.d.ts +3 -5
  12. package/dist/codec/codec.d.ts.map +1 -1
  13. package/dist/codec/codec.js +9 -2
  14. package/dist/codec/codec.js.map +1 -1
  15. package/dist/codec/index.d.ts +0 -1
  16. package/dist/codec/index.d.ts.map +1 -1
  17. package/dist/codec/index.js +1 -3
  18. package/dist/codec/index.js.map +1 -1
  19. package/dist/core/index.d.ts +1 -1
  20. package/dist/core/index.d.ts.map +1 -1
  21. package/dist/core/index.js +2 -1
  22. package/dist/core/index.js.map +1 -1
  23. package/dist/core/rebase/index.d.ts +1 -1
  24. package/dist/core/rebase/index.d.ts.map +1 -1
  25. package/dist/core/rebase/index.js +2 -1
  26. package/dist/core/rebase/index.js.map +1 -1
  27. package/dist/core/rebase/utils.d.ts +10 -0
  28. package/dist/core/rebase/utils.d.ts.map +1 -1
  29. package/dist/core/rebase/utils.js +20 -1
  30. package/dist/core/rebase/utils.js.map +1 -1
  31. package/dist/core/tree/detachedFieldIndex.js +1 -1
  32. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  33. package/dist/external-utilities/index.d.ts +1 -1
  34. package/dist/external-utilities/index.d.ts.map +1 -1
  35. package/dist/external-utilities/index.js +1 -2
  36. package/dist/external-utilities/index.js.map +1 -1
  37. package/dist/external-utilities/typeboxValidator.d.ts +0 -13
  38. package/dist/external-utilities/typeboxValidator.d.ts.map +1 -1
  39. package/dist/external-utilities/typeboxValidator.js +3 -5
  40. package/dist/external-utilities/typeboxValidator.js.map +1 -1
  41. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +2 -0
  42. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  43. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  44. package/dist/feature-libraries/flex-tree/index.d.ts +1 -0
  45. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  46. package/dist/feature-libraries/flex-tree/index.js +4 -1
  47. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  48. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  49. package/dist/feature-libraries/flex-tree/lazyNode.js +15 -8
  50. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  51. package/dist/feature-libraries/flex-tree/observer.d.ts +32 -0
  52. package/dist/feature-libraries/flex-tree/observer.d.ts.map +1 -0
  53. package/dist/feature-libraries/flex-tree/observer.js +33 -0
  54. package/dist/feature-libraries/flex-tree/observer.js.map +1 -0
  55. package/dist/feature-libraries/index.d.ts +1 -1
  56. package/dist/feature-libraries/index.d.ts.map +1 -1
  57. package/dist/feature-libraries/index.js +3 -1
  58. package/dist/feature-libraries/index.js.map +1 -1
  59. package/dist/index.d.ts +5 -5
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +9 -8
  62. package/dist/index.js.map +1 -1
  63. package/dist/legacy.d.ts +7 -1
  64. package/dist/packageVersion.d.ts +1 -1
  65. package/dist/packageVersion.js +1 -1
  66. package/dist/packageVersion.js.map +1 -1
  67. package/dist/shared-tree/index.d.ts +2 -2
  68. package/dist/shared-tree/index.d.ts.map +1 -1
  69. package/dist/shared-tree/index.js.map +1 -1
  70. package/dist/shared-tree/schematizingTreeView.js +2 -2
  71. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  72. package/dist/shared-tree/sharedTree.d.ts +21 -6
  73. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  74. package/dist/shared-tree/sharedTree.js +76 -37
  75. package/dist/shared-tree/sharedTree.js.map +1 -1
  76. package/dist/shared-tree/treeAlpha.d.ts +114 -1
  77. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  78. package/dist/shared-tree/treeAlpha.js +140 -1
  79. package/dist/shared-tree/treeAlpha.js.map +1 -1
  80. package/dist/shared-tree/treeCheckout.d.ts +13 -7
  81. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  82. package/dist/shared-tree/treeCheckout.js +115 -85
  83. package/dist/shared-tree/treeCheckout.js.map +1 -1
  84. package/dist/shared-tree-core/branch.d.ts +3 -0
  85. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  86. package/dist/shared-tree-core/branch.js.map +1 -1
  87. package/dist/shared-tree-core/branchIdCodec.d.ts +11 -0
  88. package/dist/shared-tree-core/branchIdCodec.d.ts.map +1 -0
  89. package/dist/shared-tree-core/branchIdCodec.js +18 -0
  90. package/dist/shared-tree-core/branchIdCodec.js.map +1 -0
  91. package/dist/shared-tree-core/editManager.d.ts +39 -64
  92. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  93. package/dist/shared-tree-core/editManager.js +455 -295
  94. package/dist/shared-tree-core/editManager.js.map +1 -1
  95. package/dist/shared-tree-core/editManagerCodecs.d.ts +1 -1
  96. package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  97. package/dist/shared-tree-core/editManagerCodecs.js +7 -96
  98. package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
  99. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +17 -0
  100. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -0
  101. package/dist/shared-tree-core/editManagerCodecsCommons.js +139 -0
  102. package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -0
  103. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts +16 -0
  104. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -0
  105. package/dist/shared-tree-core/editManagerCodecsV1toV4.js +39 -0
  106. package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -0
  107. package/dist/shared-tree-core/editManagerCodecsV5.d.ts +16 -0
  108. package/dist/shared-tree-core/editManagerCodecsV5.d.ts.map +1 -0
  109. package/dist/shared-tree-core/editManagerCodecsV5.js +58 -0
  110. package/dist/shared-tree-core/editManagerCodecsV5.js.map +1 -0
  111. package/dist/shared-tree-core/{editManagerFormat.d.ts → editManagerFormatCommons.d.ts} +31 -7
  112. package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -0
  113. package/dist/shared-tree-core/{editManagerFormat.js → editManagerFormatCommons.js} +13 -12
  114. package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -0
  115. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +31 -0
  116. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -0
  117. package/dist/shared-tree-core/editManagerFormatV1toV4.js +24 -0
  118. package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -0
  119. package/dist/shared-tree-core/editManagerFormatV5.d.ts +62 -0
  120. package/dist/shared-tree-core/editManagerFormatV5.d.ts.map +1 -0
  121. package/dist/shared-tree-core/editManagerFormatV5.js +20 -0
  122. package/dist/shared-tree-core/editManagerFormatV5.js.map +1 -0
  123. package/dist/shared-tree-core/index.d.ts +3 -3
  124. package/dist/shared-tree-core/index.d.ts.map +1 -1
  125. package/dist/shared-tree-core/index.js.map +1 -1
  126. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts +11 -0
  127. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -0
  128. package/dist/shared-tree-core/messageCodecV1ToV4.js +59 -0
  129. package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -0
  130. package/dist/shared-tree-core/messageCodecV5.d.ts +11 -0
  131. package/dist/shared-tree-core/messageCodecV5.d.ts.map +1 -0
  132. package/dist/shared-tree-core/messageCodecV5.js +78 -0
  133. package/dist/shared-tree-core/messageCodecV5.js.map +1 -0
  134. package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
  135. package/dist/shared-tree-core/messageCodecs.js +16 -47
  136. package/dist/shared-tree-core/messageCodecs.js.map +1 -1
  137. package/dist/shared-tree-core/{messageFormat.d.ts → messageFormatV1ToV4.d.ts} +1 -1
  138. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -0
  139. package/dist/shared-tree-core/{messageFormat.js → messageFormatV1ToV4.js} +1 -1
  140. package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -0
  141. package/dist/shared-tree-core/messageFormatV5.d.ts +42 -0
  142. package/dist/shared-tree-core/messageFormatV5.d.ts.map +1 -0
  143. package/dist/shared-tree-core/messageFormatV5.js +20 -0
  144. package/dist/shared-tree-core/messageFormatV5.js.map +1 -0
  145. package/dist/shared-tree-core/messageTypes.d.ts +12 -2
  146. package/dist/shared-tree-core/messageTypes.d.ts.map +1 -1
  147. package/dist/shared-tree-core/messageTypes.js.map +1 -1
  148. package/dist/shared-tree-core/sequenceIdUtils.d.ts +1 -1
  149. package/dist/shared-tree-core/sequenceIdUtils.d.ts.map +1 -1
  150. package/dist/shared-tree-core/sequenceIdUtils.js.map +1 -1
  151. package/dist/shared-tree-core/sharedTreeCore.d.ts +19 -5
  152. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  153. package/dist/shared-tree-core/sharedTreeCore.js +182 -58
  154. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  155. package/dist/simple-tree/api/tree.d.ts +17 -0
  156. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  157. package/dist/simple-tree/api/tree.js +2 -0
  158. package/dist/simple-tree/api/tree.js.map +1 -1
  159. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  160. package/dist/simple-tree/core/unhydratedFlexTree.js +7 -1
  161. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  162. package/dist/treeFactory.d.ts +38 -9
  163. package/dist/treeFactory.d.ts.map +1 -1
  164. package/dist/treeFactory.js +44 -9
  165. package/dist/treeFactory.js.map +1 -1
  166. package/lib/alpha.d.ts +8 -8
  167. package/lib/api.d.ts +17 -0
  168. package/lib/api.d.ts.map +1 -0
  169. package/lib/api.js +22 -0
  170. package/lib/api.js.map +1 -0
  171. package/lib/beta.d.ts +5 -0
  172. package/lib/codec/codec.d.ts +3 -5
  173. package/lib/codec/codec.d.ts.map +1 -1
  174. package/lib/codec/codec.js +8 -1
  175. package/lib/codec/codec.js.map +1 -1
  176. package/lib/codec/index.d.ts +0 -1
  177. package/lib/codec/index.d.ts.map +1 -1
  178. package/lib/codec/index.js +0 -1
  179. package/lib/codec/index.js.map +1 -1
  180. package/lib/core/index.d.ts +1 -1
  181. package/lib/core/index.d.ts.map +1 -1
  182. package/lib/core/index.js +1 -1
  183. package/lib/core/index.js.map +1 -1
  184. package/lib/core/rebase/index.d.ts +1 -1
  185. package/lib/core/rebase/index.d.ts.map +1 -1
  186. package/lib/core/rebase/index.js +1 -1
  187. package/lib/core/rebase/index.js.map +1 -1
  188. package/lib/core/rebase/utils.d.ts +10 -0
  189. package/lib/core/rebase/utils.d.ts.map +1 -1
  190. package/lib/core/rebase/utils.js +18 -0
  191. package/lib/core/rebase/utils.js.map +1 -1
  192. package/lib/core/tree/detachedFieldIndex.js +2 -2
  193. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  194. package/lib/external-utilities/index.d.ts +1 -1
  195. package/lib/external-utilities/index.d.ts.map +1 -1
  196. package/lib/external-utilities/index.js +1 -1
  197. package/lib/external-utilities/index.js.map +1 -1
  198. package/lib/external-utilities/typeboxValidator.d.ts +0 -13
  199. package/lib/external-utilities/typeboxValidator.d.ts.map +1 -1
  200. package/lib/external-utilities/typeboxValidator.js +1 -3
  201. package/lib/external-utilities/typeboxValidator.js.map +1 -1
  202. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +2 -0
  203. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  204. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  205. package/lib/feature-libraries/flex-tree/index.d.ts +1 -0
  206. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  207. package/lib/feature-libraries/flex-tree/index.js +1 -0
  208. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  209. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  210. package/lib/feature-libraries/flex-tree/lazyNode.js +15 -8
  211. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  212. package/lib/feature-libraries/flex-tree/observer.d.ts +32 -0
  213. package/lib/feature-libraries/flex-tree/observer.d.ts.map +1 -0
  214. package/lib/feature-libraries/flex-tree/observer.js +40 -0
  215. package/lib/feature-libraries/flex-tree/observer.js.map +1 -0
  216. package/lib/feature-libraries/index.d.ts +1 -1
  217. package/lib/feature-libraries/index.d.ts.map +1 -1
  218. package/lib/feature-libraries/index.js +1 -1
  219. package/lib/feature-libraries/index.js.map +1 -1
  220. package/lib/index.d.ts +5 -5
  221. package/lib/index.d.ts.map +1 -1
  222. package/lib/index.js +3 -3
  223. package/lib/index.js.map +1 -1
  224. package/lib/legacy.d.ts +7 -1
  225. package/lib/packageVersion.d.ts +1 -1
  226. package/lib/packageVersion.js +1 -1
  227. package/lib/packageVersion.js.map +1 -1
  228. package/lib/shared-tree/index.d.ts +2 -2
  229. package/lib/shared-tree/index.d.ts.map +1 -1
  230. package/lib/shared-tree/index.js.map +1 -1
  231. package/lib/shared-tree/schematizingTreeView.js +2 -2
  232. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  233. package/lib/shared-tree/sharedTree.d.ts +21 -6
  234. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  235. package/lib/shared-tree/sharedTree.js +78 -39
  236. package/lib/shared-tree/sharedTree.js.map +1 -1
  237. package/lib/shared-tree/treeAlpha.d.ts +114 -1
  238. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  239. package/lib/shared-tree/treeAlpha.js +143 -4
  240. package/lib/shared-tree/treeAlpha.js.map +1 -1
  241. package/lib/shared-tree/treeCheckout.d.ts +13 -7
  242. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  243. package/lib/shared-tree/treeCheckout.js +117 -87
  244. package/lib/shared-tree/treeCheckout.js.map +1 -1
  245. package/lib/shared-tree-core/branch.d.ts +3 -0
  246. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  247. package/lib/shared-tree-core/branch.js.map +1 -1
  248. package/lib/shared-tree-core/branchIdCodec.d.ts +11 -0
  249. package/lib/shared-tree-core/branchIdCodec.d.ts.map +1 -0
  250. package/lib/shared-tree-core/branchIdCodec.js +13 -0
  251. package/lib/shared-tree-core/branchIdCodec.js.map +1 -0
  252. package/lib/shared-tree-core/editManager.d.ts +39 -64
  253. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  254. package/lib/shared-tree-core/editManager.js +455 -295
  255. package/lib/shared-tree-core/editManager.js.map +1 -1
  256. package/lib/shared-tree-core/editManagerCodecs.d.ts +1 -1
  257. package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  258. package/lib/shared-tree-core/editManagerCodecs.js +4 -93
  259. package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
  260. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +17 -0
  261. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -0
  262. package/lib/shared-tree-core/editManagerCodecsCommons.js +134 -0
  263. package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -0
  264. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts +16 -0
  265. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -0
  266. package/lib/shared-tree-core/editManagerCodecsV1toV4.js +35 -0
  267. package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -0
  268. package/lib/shared-tree-core/editManagerCodecsV5.d.ts +16 -0
  269. package/lib/shared-tree-core/editManagerCodecsV5.d.ts.map +1 -0
  270. package/lib/shared-tree-core/editManagerCodecsV5.js +54 -0
  271. package/lib/shared-tree-core/editManagerCodecsV5.js.map +1 -0
  272. package/lib/shared-tree-core/{editManagerFormat.d.ts → editManagerFormatCommons.d.ts} +31 -7
  273. package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -0
  274. package/lib/shared-tree-core/{editManagerFormat.js → editManagerFormatCommons.js} +10 -11
  275. package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -0
  276. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +31 -0
  277. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -0
  278. package/lib/shared-tree-core/editManagerFormatV1toV4.js +20 -0
  279. package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -0
  280. package/lib/shared-tree-core/editManagerFormatV5.d.ts +62 -0
  281. package/lib/shared-tree-core/editManagerFormatV5.d.ts.map +1 -0
  282. package/lib/shared-tree-core/editManagerFormatV5.js +16 -0
  283. package/lib/shared-tree-core/editManagerFormatV5.js.map +1 -0
  284. package/lib/shared-tree-core/index.d.ts +3 -3
  285. package/lib/shared-tree-core/index.d.ts.map +1 -1
  286. package/lib/shared-tree-core/index.js.map +1 -1
  287. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts +11 -0
  288. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -0
  289. package/lib/shared-tree-core/messageCodecV1ToV4.js +55 -0
  290. package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -0
  291. package/lib/shared-tree-core/messageCodecV5.d.ts +11 -0
  292. package/lib/shared-tree-core/messageCodecV5.d.ts.map +1 -0
  293. package/lib/shared-tree-core/messageCodecV5.js +74 -0
  294. package/lib/shared-tree-core/messageCodecV5.js.map +1 -0
  295. package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
  296. package/lib/shared-tree-core/messageCodecs.js +17 -48
  297. package/lib/shared-tree-core/messageCodecs.js.map +1 -1
  298. package/lib/shared-tree-core/{messageFormat.d.ts → messageFormatV1ToV4.d.ts} +1 -1
  299. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -0
  300. package/lib/shared-tree-core/{messageFormat.js → messageFormatV1ToV4.js} +1 -1
  301. package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -0
  302. package/lib/shared-tree-core/messageFormatV5.d.ts +42 -0
  303. package/lib/shared-tree-core/messageFormatV5.d.ts.map +1 -0
  304. package/lib/shared-tree-core/messageFormatV5.js +16 -0
  305. package/lib/shared-tree-core/messageFormatV5.js.map +1 -0
  306. package/lib/shared-tree-core/messageTypes.d.ts +12 -2
  307. package/lib/shared-tree-core/messageTypes.d.ts.map +1 -1
  308. package/lib/shared-tree-core/messageTypes.js.map +1 -1
  309. package/lib/shared-tree-core/sequenceIdUtils.d.ts +1 -1
  310. package/lib/shared-tree-core/sequenceIdUtils.d.ts.map +1 -1
  311. package/lib/shared-tree-core/sequenceIdUtils.js.map +1 -1
  312. package/lib/shared-tree-core/sharedTreeCore.d.ts +19 -5
  313. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  314. package/lib/shared-tree-core/sharedTreeCore.js +183 -59
  315. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  316. package/lib/simple-tree/api/tree.d.ts +17 -0
  317. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  318. package/lib/simple-tree/api/tree.js +2 -0
  319. package/lib/simple-tree/api/tree.js.map +1 -1
  320. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  321. package/lib/simple-tree/core/unhydratedFlexTree.js +8 -2
  322. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  323. package/lib/treeFactory.d.ts +38 -9
  324. package/lib/treeFactory.d.ts.map +1 -1
  325. package/lib/treeFactory.js +41 -8
  326. package/lib/treeFactory.js.map +1 -1
  327. package/package.json +25 -25
  328. package/src/api.ts +30 -0
  329. package/src/codec/codec.ts +12 -6
  330. package/src/codec/index.ts +0 -1
  331. package/src/core/index.ts +1 -0
  332. package/src/core/rebase/index.ts +1 -0
  333. package/src/core/rebase/utils.ts +27 -0
  334. package/src/core/tree/detachedFieldIndex.ts +2 -2
  335. package/src/external-utilities/index.ts +1 -1
  336. package/src/external-utilities/typeboxValidator.ts +1 -3
  337. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +2 -0
  338. package/src/feature-libraries/flex-tree/index.ts +2 -0
  339. package/src/feature-libraries/flex-tree/lazyNode.ts +13 -3
  340. package/src/feature-libraries/flex-tree/observer.ts +64 -0
  341. package/src/feature-libraries/index.ts +3 -0
  342. package/src/index.ts +6 -4
  343. package/src/packageVersion.ts +1 -1
  344. package/src/shared-tree/index.ts +2 -0
  345. package/src/shared-tree/schematizingTreeView.ts +2 -2
  346. package/src/shared-tree/sharedTree.ts +116 -52
  347. package/src/shared-tree/treeAlpha.ts +309 -4
  348. package/src/shared-tree/treeCheckout.ts +152 -100
  349. package/src/shared-tree-core/branch.ts +7 -0
  350. package/src/shared-tree-core/branchIdCodec.ts +28 -0
  351. package/src/shared-tree-core/editManager.ts +729 -430
  352. package/src/shared-tree-core/editManagerCodecs.ts +4 -164
  353. package/src/shared-tree-core/editManagerCodecsCommons.ts +245 -0
  354. package/src/shared-tree-core/editManagerCodecsV1toV4.ts +108 -0
  355. package/src/shared-tree-core/editManagerCodecsV5.ts +156 -0
  356. package/src/shared-tree-core/{editManagerFormat.ts → editManagerFormatCommons.ts} +17 -13
  357. package/src/shared-tree-core/editManagerFormatV1toV4.ts +42 -0
  358. package/src/shared-tree-core/editManagerFormatV5.ts +35 -0
  359. package/src/shared-tree-core/index.ts +3 -1
  360. package/src/shared-tree-core/messageCodecV1ToV4.ts +104 -0
  361. package/src/shared-tree-core/messageCodecV5.ts +131 -0
  362. package/src/shared-tree-core/messageCodecs.ts +16 -85
  363. package/src/shared-tree-core/messageFormatV5.ts +50 -0
  364. package/src/shared-tree-core/messageTypes.ts +15 -2
  365. package/src/shared-tree-core/sequenceIdUtils.ts +1 -1
  366. package/src/shared-tree-core/sharedTreeCore.ts +281 -85
  367. package/src/simple-tree/api/tree.ts +23 -0
  368. package/src/simple-tree/core/unhydratedFlexTree.ts +11 -2
  369. package/src/treeFactory.ts +48 -8
  370. package/dist/codec/noopValidator.d.ts +0 -13
  371. package/dist/codec/noopValidator.d.ts.map +0 -1
  372. package/dist/codec/noopValidator.js +0 -17
  373. package/dist/codec/noopValidator.js.map +0 -1
  374. package/dist/shared-tree-core/editManagerFormat.d.ts.map +0 -1
  375. package/dist/shared-tree-core/editManagerFormat.js.map +0 -1
  376. package/dist/shared-tree-core/messageFormat.d.ts.map +0 -1
  377. package/dist/shared-tree-core/messageFormat.js.map +0 -1
  378. package/docs/user-facing/schema-evolution.md +0 -309
  379. package/lib/codec/noopValidator.d.ts +0 -13
  380. package/lib/codec/noopValidator.d.ts.map +0 -1
  381. package/lib/codec/noopValidator.js +0 -14
  382. package/lib/codec/noopValidator.js.map +0 -1
  383. package/lib/shared-tree-core/editManagerFormat.d.ts.map +0 -1
  384. package/lib/shared-tree-core/editManagerFormat.js.map +0 -1
  385. package/lib/shared-tree-core/messageFormat.d.ts.map +0 -1
  386. package/lib/shared-tree-core/messageFormat.js.map +0 -1
  387. package/src/codec/noopValidator.ts +0 -18
  388. /package/src/shared-tree-core/{messageFormat.ts → messageFormatV1ToV4.ts} +0 -0
@@ -4,10 +4,14 @@
4
4
  */
5
5
 
6
6
  import type { IFluidLoadable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
- import { assert } from "@fluidframework/core-utils/internal";
7
+ import { assert, fail, unreachableCase } from "@fluidframework/core-utils/internal";
8
8
  import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
9
9
  import type { ISnapshotTree } from "@fluidframework/driver-definitions/internal";
10
- import type { IIdCompressor, SessionId } from "@fluidframework/id-compressor";
10
+ import type {
11
+ IIdCompressor,
12
+ SessionId,
13
+ SessionSpaceCompressedId,
14
+ } from "@fluidframework/id-compressor";
11
15
  import type {
12
16
  IExperimentalIncrementalSummaryContext,
13
17
  IRuntimeMessageCollection,
@@ -42,13 +46,13 @@ import {
42
46
  breakingClass,
43
47
  } from "../util/index.js";
44
48
 
45
- import type { SharedTreeBranch } from "./branch.js";
49
+ import type { BranchId, SharedTreeBranch } from "./branch.js";
46
50
  import { BranchCommitEnricher } from "./branchCommitEnricher.js";
47
51
  import { type ChangeEnricherReadonlyCheckout, NoOpChangeEnricher } from "./changeEnricher.js";
48
52
  import { DefaultResubmitMachine } from "./defaultResubmitMachine.js";
49
53
  import { EditManager, minimumPossibleSequenceNumber } from "./editManager.js";
50
54
  import { makeEditManagerCodec } from "./editManagerCodecs.js";
51
- import type { SeqNumber } from "./editManagerFormat.js";
55
+ import type { SeqNumber } from "./editManagerFormatCommons.js";
52
56
  import { EditManagerSummarizer } from "./editManagerSummarizer.js";
53
57
  import { type MessageEncodingContext, makeMessageCodec } from "./messageCodecs.js";
54
58
  import type { DecodedMessage } from "./messageTypes.js";
@@ -98,8 +102,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
98
102
  MessageEncodingContext
99
103
  >;
100
104
 
101
- private readonly resubmitMachine: ResubmitMachine<TChange>;
102
- public readonly commitEnricher: BranchCommitEnricher<TChange>;
105
+ private readonly enrichers: Map<BranchId, EnricherState<TChange>> = new Map();
103
106
 
104
107
  public readonly mintRevisionTag: () => RevisionTag;
105
108
 
@@ -120,10 +123,10 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
120
123
  public readonly submitLocalMessage: (content: unknown, localOpMetadata?: unknown) => void,
121
124
  logger: ITelemetryBaseLogger | undefined,
122
125
  summarizables: readonly Summarizable[],
123
- changeFamily: ChangeFamily<TEditor, TChange>,
126
+ protected readonly changeFamily: ChangeFamily<TEditor, TChange>,
124
127
  options: ICodecOptions,
125
128
  formatOptions: ExplicitCoreCodecVersions,
126
- private readonly idCompressor: IIdCompressor,
129
+ protected readonly idCompressor: IIdCompressor,
127
130
  schema: TreeStoredSchemaRepository,
128
131
  schemaPolicy: SchemaPolicy,
129
132
  resubmitMachine?: ResubmitMachine<TChange>,
@@ -151,20 +154,11 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
151
154
  changeFamily,
152
155
  localSessionId,
153
156
  this.mintRevisionTag,
157
+ (branchId) => this.registerSharedBranch(branchId),
154
158
  rebaseLogger,
155
159
  );
156
160
 
157
- this.editManager.localBranch.events.on("beforeChange", (change) => {
158
- if (this.detachedRevision === undefined) {
159
- // Commit enrichment is only necessary for changes that will be submitted as ops, and changes issued while detached are not submitted.
160
- this.commitEnricher.processChange(change);
161
- }
162
- if (change.type === "append") {
163
- for (const commit of change.newCommits) {
164
- this.submitCommit(commit, this.schemaAndPolicy, false);
165
- }
166
- }
167
- });
161
+ this.registerSharedBranch("main");
168
162
 
169
163
  const revisionTagCodec = new RevisionTagCodec(idCompressor);
170
164
  const editManagerCodec = makeEditManagerCodec(
@@ -194,15 +188,11 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
194
188
  formatOptions.message,
195
189
  );
196
190
 
197
- const changeEnricher = enricher ?? new NoOpChangeEnricher();
198
- this.resubmitMachine =
199
- resubmitMachine ??
200
- new DefaultResubmitMachine(
201
- (change: TaggedChange<TChange>) =>
202
- changeFamily.rebaser.invert(change, true, this.mintRevisionTag()),
203
- changeEnricher,
204
- );
205
- this.commitEnricher = new BranchCommitEnricher(changeFamily.rebaser, changeEnricher);
191
+ this.registerSharedBranchForEditing(
192
+ "main",
193
+ enricher ?? new NoOpChangeEnricher(),
194
+ resubmitMachine,
195
+ );
206
196
  }
207
197
 
208
198
  // TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:
@@ -245,7 +235,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
245
235
 
246
236
  public async loadCore(services: IChannelStorageService): Promise<void> {
247
237
  assert(
248
- this.editManager.localBranch.getHead() === this.editManager.getTrunkHead(),
238
+ this.getLocalBranch().getHead() === this.editManager.getTrunkHead("main"),
249
239
  0xaaa /* All local changes should be applied to the trunk before loading from summary */,
250
240
  );
251
241
  const [editManagerSummarizer, ...summarizables] = this.summarizables;
@@ -259,8 +249,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
259
249
  // First, finish loading the edit manager so that we can inspect the sequence numbers of the commits on the trunk.
260
250
  await loadEditManager;
261
251
 
262
- const head = this.editManager.getTrunkHead();
263
- const latestDetachedSequenceNumber = this.editManager.getSequenceNumber(head);
252
+ const latestDetachedSequenceNumber = this.editManager.getLatestSequenceNumber();
264
253
  // When we load a summary for a tree that was never attached,
265
254
  // latestDetachedSequenceNumber is either undefined (no commits in summary) or negative (all commits in summary were made while detached).
266
255
  // We only need to update `this.detachedRevision` in the latter case.
@@ -273,6 +262,21 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
273
262
  }
274
263
  }
275
264
 
265
+ private registerSharedBranch(branchId: BranchId): void {
266
+ this.editManager.getLocalBranch(branchId).events.on("beforeChange", (change) => {
267
+ if (change.type === "append") {
268
+ if (this.detachedRevision === undefined) {
269
+ // Commit enrichment is only necessary for changes that will be submitted as ops, and changes issued while detached are not submitted.
270
+ this.getCommitEnricher(branchId).processChange(change);
271
+ }
272
+
273
+ for (const commit of change.newCommits) {
274
+ this.submitCommit(branchId, commit, this.schemaAndPolicy, false);
275
+ }
276
+ }
277
+ });
278
+ }
279
+
276
280
  private async loadSummarizable(
277
281
  summarizable: Summarizable,
278
282
  services: IChannelStorageService,
@@ -290,6 +294,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
290
294
  * and may differ from `commit` due to enrichments like detached tree refreshers.
291
295
  */
292
296
  protected submitCommit(
297
+ branchId: BranchId,
293
298
  commit: GraphCommit<TChange>,
294
299
  schemaAndPolicy: ClonableSchemaAndPolicy,
295
300
  isResubmit: boolean,
@@ -301,7 +306,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
301
306
 
302
307
  const enrichedCommit =
303
308
  this.detachedRevision === undefined && !isResubmit
304
- ? this.commitEnricher.enrich(commit)
309
+ ? this.getCommitEnricher(branchId).enrich(commit)
305
310
  : commit;
306
311
 
307
312
  // Edits submitted before the first attach are treated as sequenced because they will be included
@@ -315,26 +320,45 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
315
320
  this.editManager.localSessionId,
316
321
  newRevision,
317
322
  this.detachedRevision,
323
+ branchId,
318
324
  );
319
325
  this.editManager.advanceMinimumSequenceNumber(newRevision, false);
320
326
  return undefined;
321
327
  }
322
- const message = this.messageCodec.encode(
328
+
329
+ this.submitMessage(
323
330
  {
331
+ type: "commit",
324
332
  commit: enrichedCommit,
325
333
  sessionId: this.editManager.localSessionId,
334
+ branchId,
326
335
  },
327
- {
328
- idCompressor: this.idCompressor,
329
- schema: schemaAndPolicy,
330
- },
336
+ schemaAndPolicy,
337
+ );
338
+
339
+ this.getResubmitMachine(branchId).onCommitSubmitted(enrichedCommit);
340
+ }
341
+
342
+ protected submitBranchCreation(branchId: BranchId): void {
343
+ this.submitMessage(
344
+ { type: "branch", sessionId: this.editManager.localSessionId, branchId },
345
+ this.schemaAndPolicy,
331
346
  );
332
- this.submitLocalMessage(message, {
347
+ }
348
+
349
+ private submitMessage(
350
+ message: DecodedMessage<TChange>,
351
+ schemaAndPolicy: ClonableSchemaAndPolicy,
352
+ ): void {
353
+ const encodedMessage = this.messageCodec.encode(message, {
354
+ idCompressor: this.idCompressor,
355
+ schema: schemaAndPolicy,
356
+ });
357
+ this.submitLocalMessage(encodedMessage, {
333
358
  // Clone the schema to ensure that during resubmit the schema has not been mutated by later changes
334
359
  schema: schemaAndPolicy.schema.clone(),
335
360
  policy: schemaAndPolicy.policy,
336
361
  });
337
- this.resubmitMachine.onCommitSubmitted(enrichedCommit);
338
362
  }
339
363
 
340
364
  /**
@@ -344,43 +368,117 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
344
368
  const { envelope, local, messagesContent } = messagesCollection;
345
369
  const commits: GraphCommit<TChange>[] = [];
346
370
  let messagesSessionId: SessionId | undefined;
371
+ let branchId: BranchId | undefined;
372
+
373
+ const processBunch = (branch: BranchId): void => {
374
+ assert(messagesSessionId !== undefined, 0xada /* Messages must have a session ID */);
375
+ this.processCommits(
376
+ messagesSessionId,
377
+ brand(envelope.sequenceNumber),
378
+ brand(envelope.referenceSequenceNumber),
379
+ local,
380
+ branch,
381
+ commits,
382
+ );
383
+
384
+ commits.length = 0;
385
+ branchId = undefined;
386
+ };
347
387
 
348
388
  // Get a list of all the commits from the messages.
349
389
  for (const messageContent of messagesContent) {
350
390
  // Empty context object is passed in, as our decode function is schema-agnostic.
351
- const { commit, sessionId } = this.messageCodec.decode(messageContent.contents, {
391
+ const message = this.messageCodec.decode(messageContent.contents, {
352
392
  idCompressor: this.idCompressor,
353
393
  });
354
- commits.push(commit);
355
394
 
356
395
  if (messagesSessionId !== undefined) {
357
396
  assert(
358
- messagesSessionId === sessionId,
397
+ messagesSessionId === message.sessionId,
359
398
  0xad9 /* All messages in a bunch must have the same session ID */,
360
399
  );
361
400
  }
362
- messagesSessionId = sessionId;
401
+ messagesSessionId = message.sessionId;
402
+
403
+ const type = message.type;
404
+ switch (type) {
405
+ case "commit": {
406
+ if (branchId !== undefined && message.branchId !== branchId) {
407
+ processBunch(branchId);
408
+ }
409
+
410
+ branchId = message.branchId;
411
+ commits.push(message.commit);
412
+ break;
413
+ }
414
+ case "branch": {
415
+ if (branchId !== undefined) {
416
+ processBunch(branchId);
417
+ }
418
+ this.editManager.sequenceBranchCreation(
419
+ messagesSessionId,
420
+ brand(envelope.referenceSequenceNumber),
421
+ message.branchId,
422
+ );
423
+ break;
424
+ }
425
+ default:
426
+ unreachableCase(type);
427
+ }
363
428
  }
364
429
 
365
- assert(messagesSessionId !== undefined, 0xada /* Messages must have a session ID */);
430
+ if (branchId !== undefined) {
431
+ processBunch(branchId);
432
+ }
433
+
434
+ this.editManager.advanceMinimumSequenceNumber(brand(envelope.minimumSequenceNumber));
435
+ }
366
436
 
437
+ private processCommits(
438
+ sessionId: SessionId,
439
+ sequenceNumber: SeqNumber,
440
+ referenceSequenceNumber: SeqNumber,
441
+ isLocal: boolean,
442
+ branchId: BranchId,
443
+ commits: readonly GraphCommit<TChange>[],
444
+ ): void {
367
445
  this.editManager.addSequencedChanges(
368
446
  commits,
369
- messagesSessionId,
370
- brand(envelope.sequenceNumber),
371
- brand(envelope.referenceSequenceNumber),
447
+ sessionId,
448
+ sequenceNumber,
449
+ referenceSequenceNumber,
450
+ branchId,
372
451
  );
373
452
 
374
453
  // Update the resubmit machine for each commit applied.
375
- for (const _ of messagesContent) {
376
- this.resubmitMachine.onSequencedCommitApplied(local);
454
+ for (const _ of commits) {
455
+ this.tryGetResubmitMachine(branchId)?.onSequencedCommitApplied(isLocal);
377
456
  }
378
-
379
- this.editManager.advanceMinimumSequenceNumber(brand(envelope.minimumSequenceNumber));
380
457
  }
381
458
 
382
459
  public getLocalBranch(): SharedTreeBranch<TEditor, TChange> {
383
- return this.editManager.localBranch;
460
+ return this.editManager.getLocalBranch("main");
461
+ }
462
+
463
+ public getSharedBranchIds(): string[] {
464
+ return this.editManager
465
+ .getSharedBranchIds()
466
+ .filter((id): id is SessionSpaceCompressedId => id !== "main")
467
+ .map((id) => this.idCompressor.decompress(id));
468
+ }
469
+ public createSharedBranch(): string {
470
+ const branchId = this.idCompressor.generateCompressedId();
471
+ this.addBranch(branchId);
472
+ this.submitBranchCreation(branchId);
473
+ return this.idCompressor.decompress(branchId);
474
+ }
475
+
476
+ protected addBranch(branchId: BranchId): void {
477
+ this.editManager.addNewBranch(branchId);
478
+ }
479
+
480
+ public getSharedBranch(branchId: BranchId): SharedTreeBranch<TEditor, TChange> {
481
+ return this.editManager.getLocalBranch(branchId);
384
482
  }
385
483
 
386
484
  public didAttach(): void {
@@ -389,52 +487,150 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
389
487
 
390
488
  public reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown): void {
391
489
  // Empty context object is passed in, as our decode function is schema-agnostic.
392
- const {
393
- commit: { revision },
394
- } = this.messageCodec.decode(this.serializer.decode(content), {
490
+ const message = this.messageCodec.decode(this.serializer.decode(content), {
395
491
  idCompressor: this.idCompressor,
396
492
  });
397
- // If a resubmit phase is not already in progress, then this must be the first commit of a new resubmit phase.
398
- if (this.resubmitMachine.isInResubmitPhase === false) {
399
- const localCommits = this.editManager.getLocalCommits();
400
- const revisionIndex = localCommits.findIndex((c) => c.revision === revision);
401
- assert(revisionIndex >= 0, 0xbdb /* revision must exist in local commits */);
402
- const toResubmit = localCommits.slice(revisionIndex);
403
- this.resubmitMachine.prepareForResubmit(toResubmit);
493
+
494
+ const type = message.type;
495
+ switch (type) {
496
+ case "commit": {
497
+ const {
498
+ commit: { revision },
499
+ branchId,
500
+ } = message;
501
+
502
+ const resubmitMachine = this.getResubmitMachine(branchId);
503
+ // If a resubmit phase is not already in progress, then this must be the first commit of a new resubmit phase.
504
+ if (resubmitMachine.isInResubmitPhase === false) {
505
+ const localCommits = this.editManager.getLocalCommits(branchId);
506
+ const revisionIndex = localCommits.findIndex((c) => c.revision === revision);
507
+ assert(revisionIndex >= 0, 0xbdb /* revision must exist in local commits */);
508
+ const toResubmit = localCommits.slice(revisionIndex);
509
+ resubmitMachine.prepareForResubmit(toResubmit);
510
+ }
511
+ assert(
512
+ isClonableSchemaPolicy(localOpMetadata),
513
+ 0x95e /* Local metadata must contain schema and policy. */,
514
+ );
515
+ assert(
516
+ resubmitMachine.isInResubmitPhase !== false,
517
+ 0x984 /* Invalid resubmit outside of resubmit phase */,
518
+ );
519
+ const enrichedCommit = resubmitMachine.peekNextCommit();
520
+ this.submitCommit(branchId, enrichedCommit, localOpMetadata, true);
521
+ break;
522
+ }
523
+ case "branch": {
524
+ this.submitBranchCreation(message.branchId);
525
+ break;
526
+ }
527
+ default:
528
+ unreachableCase(type);
404
529
  }
405
- assert(
406
- isClonableSchemaPolicy(localOpMetadata),
407
- 0x95e /* Local metadata must contain schema and policy. */,
408
- );
409
- assert(
410
- this.resubmitMachine.isInResubmitPhase !== false,
411
- 0x984 /* Invalid resubmit outside of resubmit phase */,
412
- );
413
- const enrichedCommit = this.resubmitMachine.peekNextCommit();
414
- this.submitCommit(enrichedCommit, localOpMetadata, true);
415
530
  }
531
+
416
532
  public rollback(content: JsonCompatibleReadOnly, localOpMetadata: unknown): void {
417
533
  // Empty context object is passed in, as our decode function is schema-agnostic.
418
- const {
419
- commit: { revision },
420
- } = this.messageCodec.decode(this.serializer.decode(content), {
534
+ const message = this.messageCodec.decode(this.serializer.decode(content), {
421
535
  idCompressor: this.idCompressor,
422
536
  });
423
- const [commit] = this.editManager.findLocalCommit(revision);
424
- const { parent } = commit;
425
- assert(parent !== undefined, 0xbdc /* must have parent */);
426
- const [precedingCommit] = this.editManager.findLocalCommit(parent.revision);
427
- this.editManager.localBranch.removeAfter(precedingCommit);
428
- this.resubmitMachine.onCommitRollback(commit);
537
+
538
+ const type = message.type;
539
+ switch (type) {
540
+ case "commit": {
541
+ const {
542
+ commit: { revision },
543
+ branchId,
544
+ } = message;
545
+ const branch = this.editManager.getLocalBranch(branchId);
546
+ const head = branch.getHead();
547
+ assert(head.revision === revision, 0xc6b /* Can only rollback latest commit */);
548
+ const newHead = head.parent ?? fail(0xc6c /* must have parent */);
549
+ branch.removeAfter(newHead);
550
+ this.getResubmitMachine(branchId).onCommitRollback(head);
551
+ break;
552
+ }
553
+ case "branch": {
554
+ this.editManager.removeBranch(message.branchId);
555
+ break;
556
+ }
557
+ default:
558
+ unreachableCase(type);
559
+ }
429
560
  }
430
561
 
431
562
  public applyStashedOp(content: JsonCompatibleReadOnly): void {
432
563
  // Empty context object is passed in, as our decode function is schema-agnostic.
433
- const {
434
- commit: { revision, change },
435
- } = this.messageCodec.decode(content, { idCompressor: this.idCompressor });
436
- this.editManager.localBranch.apply({ change, revision });
564
+ const message = this.messageCodec.decode(this.serializer.decode(content), {
565
+ idCompressor: this.idCompressor,
566
+ });
567
+
568
+ const type = message.type;
569
+ switch (type) {
570
+ case "commit": {
571
+ const {
572
+ commit: { revision, change },
573
+ branchId,
574
+ } = message;
575
+ this.editManager.getLocalBranch(branchId).apply({ change, revision });
576
+ break;
577
+ }
578
+ case "branch": {
579
+ this.editManager.addNewBranch(message.branchId);
580
+ break;
581
+ }
582
+ default:
583
+ unreachableCase(type);
584
+ }
585
+ }
586
+
587
+ protected registerSharedBranchForEditing(
588
+ branchId: BranchId,
589
+ enricher: ChangeEnricherReadonlyCheckout<TChange>,
590
+ resubmitMachine?: ResubmitMachine<TChange>,
591
+ ): void {
592
+ const changeEnricher = enricher ?? new NoOpChangeEnricher();
593
+ const commitEnricher = new BranchCommitEnricher(this.changeFamily.rebaser, changeEnricher);
594
+ assert(!this.enrichers.has(branchId), 0xc6d /* Branch already registered */);
595
+ this.enrichers.set(branchId, {
596
+ enricher: commitEnricher,
597
+ resubmitMachine:
598
+ resubmitMachine ??
599
+ new DefaultResubmitMachine(
600
+ (change: TaggedChange<TChange>) =>
601
+ this.changeFamily.rebaser.invert(change, true, this.mintRevisionTag()),
602
+ changeEnricher,
603
+ ),
604
+ });
605
+ }
606
+
607
+ private getResubmitMachine(branchId: BranchId): ResubmitMachine<TChange> {
608
+ return this.getEnricherState(branchId).resubmitMachine;
437
609
  }
610
+
611
+ private tryGetResubmitMachine(branchId: BranchId): ResubmitMachine<TChange> | undefined {
612
+ return this.tryGetEnricherState(branchId)?.resubmitMachine;
613
+ }
614
+
615
+ public getCommitEnricher(branchId: BranchId): BranchCommitEnricher<TChange> {
616
+ return this.getEnricherState(branchId).enricher;
617
+ }
618
+
619
+ private getEnricherState(branchId: BranchId): EnricherState<TChange> {
620
+ return (
621
+ this.tryGetEnricherState(branchId) ??
622
+ fail(0xc6e /* Expected to have a resubmit machine for this branch */)
623
+ );
624
+ }
625
+
626
+ private tryGetEnricherState(branchId: BranchId): EnricherState<TChange> | undefined {
627
+ return this.enrichers.get(branchId);
628
+ }
629
+ }
630
+
631
+ interface EnricherState<TChange> {
632
+ readonly enricher: BranchCommitEnricher<TChange>;
633
+ readonly resubmitMachine: ResubmitMachine<TChange>;
438
634
  }
439
635
 
440
636
  function isClonableSchemaPolicy(
@@ -99,6 +99,27 @@ export interface ITreeAlpha extends ITree {
99
99
  * To get the schema using property keys, use {@link getSimpleSchema} on the view schema.
100
100
  */
101
101
  exportSimpleSchema(): SimpleTreeSchema;
102
+
103
+ /**
104
+ * Creates a fork of the current state of the main branch.
105
+ * This new branch will be shared with and editable by all clients.
106
+ */
107
+ createSharedBranch(): string;
108
+
109
+ /**
110
+ * Returns a list of all shared branches that currently exist on this tree.
111
+ * Any one of them can be checked out using {@link ITreeAlpha.viewSharedBranchWith}.
112
+ */
113
+ getSharedBranchIds(): string[];
114
+
115
+ /**
116
+ * Returns a view of the tree on the specified shared branch, using the provided schema.
117
+ * See {@link ViewableTree.viewWith}.
118
+ */
119
+ viewSharedBranchWith<TRoot extends ImplicitFieldSchema>(
120
+ branchId: string,
121
+ config: TreeViewConfiguration<TRoot>,
122
+ ): TreeView<TRoot>;
102
123
  }
103
124
 
104
125
  /**
@@ -517,6 +538,8 @@ export interface TreeViewEvents {
517
538
  /**
518
539
  * Retrieve the {@link TreeViewAlpha | alpha API} for a {@link TreeView}.
519
540
  * @alpha
541
+ * @deprecated Use {@link asAlpha} instead.
542
+ * @privateRemarks Despite being deprecated, this function should be used within the tree package (outside of tests) rather than `asAlpha` in order to avoid circular import dependencies.
520
543
  */
521
544
  export function asTreeViewAlpha<TSchema extends ImplicitFieldSchema>(
522
545
  view: TreeView<TSchema>,
@@ -50,6 +50,7 @@ import {
50
50
  type HydratedFlexTreeNode,
51
51
  cursorForMapTreeField,
52
52
  type MinimalFieldMap,
53
+ currentObserver,
53
54
  } from "../../feature-libraries/index.js";
54
55
  import { brand, filterIterable, getOrCreate, mapIterable } from "../../util/index.js";
55
56
 
@@ -144,8 +145,10 @@ export class UnhydratedFlexTreeNode
144
145
  */
145
146
  public readonly fields: MinimalFieldMap<UnhydratedFlexTreeField> = {
146
147
  get: (key: FieldKey): UnhydratedFlexTreeField | undefined => this.tryGetField(key),
147
- [Symbol.iterator]: (): IterableIterator<[FieldKey, UnhydratedFlexTreeField]> =>
148
- filterIterable(this.fieldsAll, ([, field]) => field.length > 0),
148
+ [Symbol.iterator]: (): IterableIterator<[FieldKey, UnhydratedFlexTreeField]> => {
149
+ currentObserver?.observeNodeFields(this);
150
+ return filterIterable(this.fieldsAll, ([, field]) => field.length > 0);
151
+ },
149
152
  };
150
153
 
151
154
  public [Symbol.iterator](): IterableIterator<UnhydratedFlexTreeField> {
@@ -218,6 +221,7 @@ export class UnhydratedFlexTreeNode
218
221
  * @remarks If this node is unparented, this method will return the special {@link unparentedLocation} as the parent.
219
222
  */
220
223
  public get parentField(): LocationInField {
224
+ currentObserver?.observeParentOf(this);
221
225
  return this.location;
222
226
  }
223
227
 
@@ -226,6 +230,8 @@ export class UnhydratedFlexTreeNode
226
230
  }
227
231
 
228
232
  public tryGetField(key: FieldKey): UnhydratedFlexTreeField | undefined {
233
+ currentObserver?.observeNodeField(this, key);
234
+
229
235
  const field = this.fieldsAll.get(key);
230
236
  // Only return the field if it is not empty, in order to fulfill the contract of `tryGetField`.
231
237
  if (field !== undefined && field.length > 0) {
@@ -235,6 +241,9 @@ export class UnhydratedFlexTreeNode
235
241
 
236
242
  public getBoxed(key: string): UnhydratedFlexTreeField {
237
243
  const fieldKey: FieldKey = brand(key);
244
+
245
+ currentObserver?.observeNodeField(this, fieldKey);
246
+
238
247
  return this.getOrCreateField(fieldKey);
239
248
  }
240
249
 
@@ -20,6 +20,7 @@ import {
20
20
  SharedTreeKernel,
21
21
  type ITreePrivate,
22
22
  type SharedTreeOptions,
23
+ type SharedTreeOptionsBeta,
23
24
  type SharedTreeOptionsInternal,
24
25
  type SharedTreeKernelView,
25
26
  } from "./shared-tree/index.js";
@@ -91,26 +92,65 @@ export const SharedTree = configuredSharedTree({});
91
92
  /**
92
93
  * {@link SharedTree} but allowing a non-default configuration.
93
94
  * @remarks
94
- * This is useful for debugging and testing to opt into extra validation or see if opting out of some optimizations fixes an issue.
95
+ * This is useful for debugging and testing.
96
+ * For example it can be used to opt into extra validation or see if opting out of some optimizations fixes an issue.
97
+ *
98
+ * With great care, and knowledge of the support and stability of the options exposed here,
99
+ * this can also be used to opt into some features early or for performance tuning.
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * import {
104
+ * configuredSharedTreeBeta,
105
+ * ForestTypeReference,
106
+ * } from "fluid-framework/beta";
107
+ * const SharedTree = configuredSharedTree({
108
+ * forest: ForestTypeReference,
109
+ * });
110
+ * ```
111
+ * @privateRemarks
112
+ * The Legacy `ISharedObjectKind<ITree>` type is omitted here for simplicity.
113
+ * @beta
114
+ */
115
+ export function configuredSharedTreeBeta(
116
+ options: SharedTreeOptionsBeta,
117
+ ): SharedObjectKind<ITree> {
118
+ return configuredSharedTree(options);
119
+ }
120
+
121
+ /**
122
+ * {@link configuredSharedTreeBeta} including the legacy `ISharedObjectKind` type.
123
+ * @privateRemarks
124
+ * This is given a different export name (with legacy appended) to avoid the need to do the special reexport with different types from the fluid-framework package.
125
+ * @legacy @beta
126
+ */
127
+ export function configuredSharedTreeBetaLegacy(
128
+ options: SharedTreeOptionsBeta,
129
+ ): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {
130
+ return configuredSharedTree(options);
131
+ }
132
+
133
+ /**
134
+ * {@link configuredSharedTreeBetaLegacy} but including `@alpha` options.
135
+ *
95
136
  * @example
96
137
  * ```typescript
97
138
  * import {
98
- * ForestType,
99
139
  * TreeCompressionStrategy,
100
140
  * configuredSharedTree,
101
- * typeboxValidator,
141
+ * FormatValidatorBasic,
142
+ * ForestTypeReference,
102
143
  * } from "@fluidframework/tree/internal";
103
144
  * const SharedTree = configuredSharedTree({
104
145
  * forest: ForestTypeReference,
105
- * jsonValidator: typeboxValidator,
146
+ * jsonValidator: FormatValidatorBasic,
106
147
  * treeEncodeType: TreeCompressionStrategy.Uncompressed,
107
148
  * });
108
149
  * ```
109
150
  * @privateRemarks
110
- * This should be legacy, but has to be internal due to limitations of API tagging preventing it from being both alpha and alpha+legacy.
111
- * TODO:
112
- * Expose Ajv validator for better error message quality somehow.
113
- * Maybe as part of a test utils or dev-tool package?
151
+ * This should be legacy, but has to be internal due to no alpha+legacy being setup yet.
152
+ *
153
+ * This should be renamed to `configuredSharedTreeAlpha` to avoid colliding with the eventual public version which will have less options.
114
154
  * @internal
115
155
  */
116
156
  export function configuredSharedTree(