@fluidframework/tree 2.10.0 → 2.11.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 (465) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/api-report/tree.alpha.api.md +47 -16
  3. package/api-report/tree.beta.api.md +5 -14
  4. package/api-report/tree.legacy.alpha.api.md +5 -14
  5. package/api-report/tree.legacy.public.api.md +5 -14
  6. package/api-report/tree.public.api.md +5 -14
  7. package/dist/alpha.d.ts +9 -0
  8. package/dist/core/forest/forest.d.ts +10 -2
  9. package/dist/core/forest/forest.d.ts.map +1 -1
  10. package/dist/core/forest/forest.js.map +1 -1
  11. package/dist/core/index.d.ts +2 -2
  12. package/dist/core/index.d.ts.map +1 -1
  13. package/dist/core/index.js +3 -2
  14. package/dist/core/index.js.map +1 -1
  15. package/dist/core/rebase/utils.d.ts +1 -1
  16. package/dist/core/rebase/utils.d.ts.map +1 -1
  17. package/dist/core/rebase/utils.js +11 -8
  18. package/dist/core/rebase/utils.js.map +1 -1
  19. package/dist/core/revertible.d.ts +30 -1
  20. package/dist/core/revertible.d.ts.map +1 -1
  21. package/dist/core/revertible.js.map +1 -1
  22. package/dist/core/schema-stored/storedSchemaRepository.d.ts +2 -2
  23. package/dist/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
  24. package/dist/core/schema-stored/storedSchemaRepository.js +5 -5
  25. package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
  26. package/dist/core/tree/anchorSet.d.ts +2 -2
  27. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  28. package/dist/core/tree/anchorSet.js +21 -21
  29. package/dist/core/tree/anchorSet.js.map +1 -1
  30. package/dist/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
  31. package/dist/core/tree/detachedFieldIndexCodec.js +3 -2
  32. package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
  33. package/dist/core/tree/index.d.ts +1 -1
  34. package/dist/core/tree/index.d.ts.map +1 -1
  35. package/dist/core/tree/index.js +2 -1
  36. package/dist/core/tree/index.js.map +1 -1
  37. package/dist/core/tree/visitorUtils.d.ts +25 -1
  38. package/dist/core/tree/visitorUtils.d.ts.map +1 -1
  39. package/dist/core/tree/visitorUtils.js +29 -1
  40. package/dist/core/tree/visitorUtils.js.map +1 -1
  41. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +5 -2
  42. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  43. package/dist/feature-libraries/chunked-forest/chunkedForest.js +24 -14
  44. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  45. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  46. package/dist/feature-libraries/chunked-forest/uniformChunk.js +2 -2
  47. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  48. package/dist/feature-libraries/flex-tree/context.d.ts +1 -1
  49. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  50. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  51. package/dist/feature-libraries/index.d.ts +1 -0
  52. package/dist/feature-libraries/index.d.ts.map +1 -1
  53. package/dist/feature-libraries/index.js +4 -1
  54. package/dist/feature-libraries/index.js.map +1 -1
  55. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts +132 -0
  56. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -0
  57. package/dist/feature-libraries/indexing/anchorTreeIndex.js +361 -0
  58. package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -0
  59. package/dist/feature-libraries/indexing/index.d.ts +7 -0
  60. package/dist/feature-libraries/indexing/index.d.ts.map +1 -0
  61. package/dist/feature-libraries/indexing/index.js +11 -0
  62. package/dist/feature-libraries/indexing/index.js.map +1 -0
  63. package/dist/feature-libraries/indexing/types.d.ts +32 -0
  64. package/dist/feature-libraries/indexing/types.d.ts.map +1 -0
  65. package/dist/{events/interop.js → feature-libraries/indexing/types.js} +1 -1
  66. package/dist/feature-libraries/indexing/types.js.map +1 -0
  67. package/dist/feature-libraries/object-forest/objectForest.d.ts +5 -2
  68. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  69. package/dist/feature-libraries/object-forest/objectForest.js +21 -11
  70. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  71. package/dist/feature-libraries/sequence-field/invert.d.ts.map +1 -1
  72. package/dist/feature-libraries/sequence-field/invert.js +2 -2
  73. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  74. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +3 -2
  75. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  76. package/dist/index.d.ts +4 -4
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +4 -1
  79. package/dist/index.js.map +1 -1
  80. package/dist/packageVersion.d.ts +1 -1
  81. package/dist/packageVersion.js +1 -1
  82. package/dist/packageVersion.js.map +1 -1
  83. package/dist/shared-tree/index.d.ts +1 -1
  84. package/dist/shared-tree/index.d.ts.map +1 -1
  85. package/dist/shared-tree/index.js +1 -2
  86. package/dist/shared-tree/index.js.map +1 -1
  87. package/dist/shared-tree/schematizingTreeView.d.ts +7 -1
  88. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  89. package/dist/shared-tree/schematizingTreeView.js +31 -30
  90. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  91. package/dist/shared-tree/sharedTree.d.ts +3 -0
  92. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  93. package/dist/shared-tree/sharedTree.js +56 -20
  94. package/dist/shared-tree/sharedTree.js.map +1 -1
  95. package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  96. package/dist/shared-tree/sharedTreeChangeFamily.js +3 -3
  97. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  98. package/dist/shared-tree/treeCheckout.d.ts +28 -64
  99. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  100. package/dist/shared-tree/treeCheckout.js +152 -129
  101. package/dist/shared-tree/treeCheckout.js.map +1 -1
  102. package/dist/shared-tree-core/branch.d.ts +25 -81
  103. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  104. package/dist/shared-tree-core/branch.js +72 -151
  105. package/dist/shared-tree-core/branch.js.map +1 -1
  106. package/dist/shared-tree-core/branchCommitEnricher.d.ts +19 -33
  107. package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  108. package/dist/shared-tree-core/branchCommitEnricher.js +73 -54
  109. package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
  110. package/dist/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
  111. package/dist/shared-tree-core/defaultResubmitMachine.js +2 -1
  112. package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  113. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  114. package/dist/shared-tree-core/editManager.js +2 -2
  115. package/dist/shared-tree-core/editManager.js.map +1 -1
  116. package/dist/shared-tree-core/index.d.ts +1 -1
  117. package/dist/shared-tree-core/index.d.ts.map +1 -1
  118. package/dist/shared-tree-core/index.js +4 -3
  119. package/dist/shared-tree-core/index.js.map +1 -1
  120. package/dist/shared-tree-core/sharedTreeCore.d.ts +2 -2
  121. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  122. package/dist/shared-tree-core/sharedTreeCore.js +11 -52
  123. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  124. package/dist/shared-tree-core/transaction.d.ts +108 -0
  125. package/dist/shared-tree-core/transaction.d.ts.map +1 -0
  126. package/dist/shared-tree-core/transaction.js +99 -0
  127. package/dist/shared-tree-core/transaction.js.map +1 -0
  128. package/dist/shared-tree-core/transactionEnricher.d.ts +8 -13
  129. package/dist/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  130. package/dist/shared-tree-core/transactionEnricher.js +41 -21
  131. package/dist/shared-tree-core/transactionEnricher.js.map +1 -1
  132. package/dist/simple-tree/api/identifierIndex.d.ts +21 -0
  133. package/dist/simple-tree/api/identifierIndex.d.ts.map +1 -0
  134. package/dist/simple-tree/api/identifierIndex.js +45 -0
  135. package/dist/simple-tree/api/identifierIndex.js.map +1 -0
  136. package/dist/simple-tree/api/index.d.ts +2 -0
  137. package/dist/simple-tree/api/index.d.ts.map +1 -1
  138. package/dist/simple-tree/api/index.js +5 -1
  139. package/dist/simple-tree/api/index.js.map +1 -1
  140. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +9 -7
  141. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  142. package/dist/simple-tree/api/simpleTreeIndex.d.ts +65 -0
  143. package/dist/simple-tree/api/simpleTreeIndex.d.ts.map +1 -0
  144. package/dist/simple-tree/api/simpleTreeIndex.js +91 -0
  145. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -0
  146. package/dist/simple-tree/api/tree.d.ts +4 -5
  147. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  148. package/dist/simple-tree/api/tree.js.map +1 -1
  149. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  150. package/dist/simple-tree/core/index.d.ts +1 -1
  151. package/dist/simple-tree/core/index.d.ts.map +1 -1
  152. package/dist/simple-tree/core/index.js +2 -1
  153. package/dist/simple-tree/core/index.js.map +1 -1
  154. package/dist/simple-tree/core/treeNodeKernel.d.ts +6 -2
  155. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  156. package/dist/simple-tree/core/treeNodeKernel.js +53 -22
  157. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  158. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +1 -1
  159. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  160. package/dist/simple-tree/core/unhydratedFlexTree.js +2 -2
  161. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  162. package/dist/simple-tree/index.d.ts +1 -1
  163. package/dist/simple-tree/index.d.ts.map +1 -1
  164. package/dist/simple-tree/index.js +4 -2
  165. package/dist/simple-tree/index.js.map +1 -1
  166. package/dist/simple-tree/objectNode.d.ts +7 -2
  167. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  168. package/dist/simple-tree/objectNode.js.map +1 -1
  169. package/dist/simple-tree/toMapTree.js +3 -3
  170. package/dist/simple-tree/toMapTree.js.map +1 -1
  171. package/dist/util/index.d.ts +1 -2
  172. package/dist/util/index.d.ts.map +1 -1
  173. package/dist/util/index.js +5 -4
  174. package/dist/util/index.js.map +1 -1
  175. package/dist/util/typeCheck.d.ts +6 -1
  176. package/dist/util/typeCheck.d.ts.map +1 -1
  177. package/dist/util/typeCheck.js.map +1 -1
  178. package/dist/util/typeCheckTests.d.ts +14 -2
  179. package/dist/util/typeCheckTests.d.ts.map +1 -1
  180. package/dist/util/typeCheckTests.js.map +1 -1
  181. package/dist/util/utils.d.ts +29 -0
  182. package/dist/util/utils.d.ts.map +1 -1
  183. package/dist/util/utils.js +13 -1
  184. package/dist/util/utils.js.map +1 -1
  185. package/lib/alpha.d.ts +9 -0
  186. package/lib/core/forest/forest.d.ts +10 -2
  187. package/lib/core/forest/forest.d.ts.map +1 -1
  188. package/lib/core/forest/forest.js.map +1 -1
  189. package/lib/core/index.d.ts +2 -2
  190. package/lib/core/index.d.ts.map +1 -1
  191. package/lib/core/index.js +2 -2
  192. package/lib/core/index.js.map +1 -1
  193. package/lib/core/rebase/utils.d.ts +1 -1
  194. package/lib/core/rebase/utils.d.ts.map +1 -1
  195. package/lib/core/rebase/utils.js +11 -8
  196. package/lib/core/rebase/utils.js.map +1 -1
  197. package/lib/core/revertible.d.ts +30 -1
  198. package/lib/core/revertible.d.ts.map +1 -1
  199. package/lib/core/revertible.js.map +1 -1
  200. package/lib/core/schema-stored/storedSchemaRepository.d.ts +2 -2
  201. package/lib/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
  202. package/lib/core/schema-stored/storedSchemaRepository.js +1 -1
  203. package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
  204. package/lib/core/tree/anchorSet.d.ts +2 -2
  205. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  206. package/lib/core/tree/anchorSet.js +1 -1
  207. package/lib/core/tree/anchorSet.js.map +1 -1
  208. package/lib/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
  209. package/lib/core/tree/detachedFieldIndexCodec.js +4 -3
  210. package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
  211. package/lib/core/tree/index.d.ts +1 -1
  212. package/lib/core/tree/index.d.ts.map +1 -1
  213. package/lib/core/tree/index.js +1 -1
  214. package/lib/core/tree/index.js.map +1 -1
  215. package/lib/core/tree/visitorUtils.d.ts +25 -1
  216. package/lib/core/tree/visitorUtils.d.ts.map +1 -1
  217. package/lib/core/tree/visitorUtils.js +27 -0
  218. package/lib/core/tree/visitorUtils.js.map +1 -1
  219. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +5 -2
  220. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  221. package/lib/feature-libraries/chunked-forest/chunkedForest.js +18 -8
  222. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  223. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  224. package/lib/feature-libraries/chunked-forest/uniformChunk.js +3 -3
  225. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  226. package/lib/feature-libraries/flex-tree/context.d.ts +1 -1
  227. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  228. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  229. package/lib/feature-libraries/index.d.ts +1 -0
  230. package/lib/feature-libraries/index.d.ts.map +1 -1
  231. package/lib/feature-libraries/index.js +1 -0
  232. package/lib/feature-libraries/index.js.map +1 -1
  233. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts +132 -0
  234. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -0
  235. package/lib/feature-libraries/indexing/anchorTreeIndex.js +356 -0
  236. package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -0
  237. package/lib/feature-libraries/indexing/index.d.ts +7 -0
  238. package/lib/feature-libraries/indexing/index.d.ts.map +1 -0
  239. package/lib/{events → feature-libraries/indexing}/index.js +1 -1
  240. package/lib/feature-libraries/indexing/index.js.map +1 -0
  241. package/lib/feature-libraries/indexing/types.d.ts +32 -0
  242. package/lib/feature-libraries/indexing/types.d.ts.map +1 -0
  243. package/lib/{events/interop.js → feature-libraries/indexing/types.js} +1 -1
  244. package/lib/feature-libraries/indexing/types.js.map +1 -0
  245. package/lib/feature-libraries/object-forest/objectForest.d.ts +5 -2
  246. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  247. package/lib/feature-libraries/object-forest/objectForest.js +15 -5
  248. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  249. package/lib/feature-libraries/sequence-field/invert.d.ts.map +1 -1
  250. package/lib/feature-libraries/sequence-field/invert.js +4 -4
  251. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  252. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +4 -3
  253. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  254. package/lib/index.d.ts +4 -4
  255. package/lib/index.d.ts.map +1 -1
  256. package/lib/index.js +1 -1
  257. package/lib/index.js.map +1 -1
  258. package/lib/packageVersion.d.ts +1 -1
  259. package/lib/packageVersion.js +1 -1
  260. package/lib/packageVersion.js.map +1 -1
  261. package/lib/shared-tree/index.d.ts +1 -1
  262. package/lib/shared-tree/index.d.ts.map +1 -1
  263. package/lib/shared-tree/index.js +1 -1
  264. package/lib/shared-tree/index.js.map +1 -1
  265. package/lib/shared-tree/schematizingTreeView.d.ts +7 -1
  266. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  267. package/lib/shared-tree/schematizingTreeView.js +2 -2
  268. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  269. package/lib/shared-tree/sharedTree.d.ts +3 -0
  270. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  271. package/lib/shared-tree/sharedTree.js +37 -1
  272. package/lib/shared-tree/sharedTree.js.map +1 -1
  273. package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  274. package/lib/shared-tree/sharedTreeChangeFamily.js +5 -5
  275. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  276. package/lib/shared-tree/treeCheckout.d.ts +28 -64
  277. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  278. package/lib/shared-tree/treeCheckout.js +140 -116
  279. package/lib/shared-tree/treeCheckout.js.map +1 -1
  280. package/lib/shared-tree-core/branch.d.ts +25 -81
  281. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  282. package/lib/shared-tree-core/branch.js +72 -151
  283. package/lib/shared-tree-core/branch.js.map +1 -1
  284. package/lib/shared-tree-core/branchCommitEnricher.d.ts +19 -33
  285. package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  286. package/lib/shared-tree-core/branchCommitEnricher.js +74 -55
  287. package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
  288. package/lib/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
  289. package/lib/shared-tree-core/defaultResubmitMachine.js +3 -2
  290. package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  291. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  292. package/lib/shared-tree-core/editManager.js +1 -1
  293. package/lib/shared-tree-core/editManager.js.map +1 -1
  294. package/lib/shared-tree-core/index.d.ts +1 -1
  295. package/lib/shared-tree-core/index.d.ts.map +1 -1
  296. package/lib/shared-tree-core/index.js +1 -1
  297. package/lib/shared-tree-core/index.js.map +1 -1
  298. package/lib/shared-tree-core/sharedTreeCore.d.ts +2 -2
  299. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  300. package/lib/shared-tree-core/sharedTreeCore.js +12 -53
  301. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  302. package/lib/shared-tree-core/transaction.d.ts +108 -0
  303. package/lib/shared-tree-core/transaction.d.ts.map +1 -0
  304. package/lib/shared-tree-core/transaction.js +95 -0
  305. package/lib/shared-tree-core/transaction.js.map +1 -0
  306. package/lib/shared-tree-core/transactionEnricher.d.ts +8 -13
  307. package/lib/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  308. package/lib/shared-tree-core/transactionEnricher.js +41 -21
  309. package/lib/shared-tree-core/transactionEnricher.js.map +1 -1
  310. package/lib/simple-tree/api/identifierIndex.d.ts +21 -0
  311. package/lib/simple-tree/api/identifierIndex.d.ts.map +1 -0
  312. package/lib/simple-tree/api/identifierIndex.js +41 -0
  313. package/lib/simple-tree/api/identifierIndex.js.map +1 -0
  314. package/lib/simple-tree/api/index.d.ts +2 -0
  315. package/lib/simple-tree/api/index.d.ts.map +1 -1
  316. package/lib/simple-tree/api/index.js +2 -0
  317. package/lib/simple-tree/api/index.js.map +1 -1
  318. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +11 -9
  319. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  320. package/lib/simple-tree/api/simpleTreeIndex.d.ts +65 -0
  321. package/lib/simple-tree/api/simpleTreeIndex.d.ts.map +1 -0
  322. package/lib/simple-tree/api/simpleTreeIndex.js +87 -0
  323. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -0
  324. package/lib/simple-tree/api/tree.d.ts +4 -5
  325. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  326. package/lib/simple-tree/api/tree.js.map +1 -1
  327. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  328. package/lib/simple-tree/core/index.d.ts +1 -1
  329. package/lib/simple-tree/core/index.d.ts.map +1 -1
  330. package/lib/simple-tree/core/index.js +1 -1
  331. package/lib/simple-tree/core/index.js.map +1 -1
  332. package/lib/simple-tree/core/treeNodeKernel.d.ts +6 -2
  333. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  334. package/lib/simple-tree/core/treeNodeKernel.js +31 -1
  335. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  336. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +1 -1
  337. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  338. package/lib/simple-tree/core/unhydratedFlexTree.js +1 -1
  339. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  340. package/lib/simple-tree/index.d.ts +1 -1
  341. package/lib/simple-tree/index.d.ts.map +1 -1
  342. package/lib/simple-tree/index.js +1 -1
  343. package/lib/simple-tree/index.js.map +1 -1
  344. package/lib/simple-tree/objectNode.d.ts +7 -2
  345. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  346. package/lib/simple-tree/objectNode.js.map +1 -1
  347. package/lib/simple-tree/toMapTree.js +5 -5
  348. package/lib/simple-tree/toMapTree.js.map +1 -1
  349. package/lib/util/index.d.ts +1 -2
  350. package/lib/util/index.d.ts.map +1 -1
  351. package/lib/util/index.js +1 -2
  352. package/lib/util/index.js.map +1 -1
  353. package/lib/util/typeCheck.d.ts +6 -1
  354. package/lib/util/typeCheck.d.ts.map +1 -1
  355. package/lib/util/typeCheck.js.map +1 -1
  356. package/lib/util/typeCheckTests.d.ts +14 -2
  357. package/lib/util/typeCheckTests.d.ts.map +1 -1
  358. package/lib/util/typeCheckTests.js.map +1 -1
  359. package/lib/util/utils.d.ts +29 -0
  360. package/lib/util/utils.d.ts.map +1 -1
  361. package/lib/util/utils.js +9 -0
  362. package/lib/util/utils.js.map +1 -1
  363. package/package.json +22 -22
  364. package/src/core/forest/forest.ts +12 -1
  365. package/src/core/index.ts +8 -1
  366. package/src/core/rebase/utils.ts +12 -10
  367. package/src/core/revertible.ts +35 -1
  368. package/src/core/schema-stored/storedSchemaRepository.ts +2 -1
  369. package/src/core/tree/anchorSet.ts +2 -1
  370. package/src/core/tree/detachedFieldIndexCodec.ts +4 -3
  371. package/src/core/tree/index.ts +1 -0
  372. package/src/core/tree/visitorUtils.ts +56 -1
  373. package/src/feature-libraries/chunked-forest/chunkedForest.ts +33 -7
  374. package/src/feature-libraries/chunked-forest/uniformChunk.ts +3 -3
  375. package/src/feature-libraries/flex-tree/context.ts +1 -1
  376. package/src/feature-libraries/index.ts +9 -0
  377. package/src/feature-libraries/indexing/anchorTreeIndex.ts +453 -0
  378. package/src/feature-libraries/indexing/index.ts +11 -0
  379. package/src/feature-libraries/indexing/types.ts +37 -0
  380. package/src/feature-libraries/object-forest/objectForest.ts +22 -4
  381. package/src/feature-libraries/sequence-field/invert.ts +4 -4
  382. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +4 -4
  383. package/src/index.ts +16 -6
  384. package/src/packageVersion.ts +1 -1
  385. package/src/shared-tree/index.ts +0 -2
  386. package/src/shared-tree/schematizingTreeView.ts +7 -7
  387. package/src/shared-tree/sharedTree.ts +60 -6
  388. package/src/shared-tree/sharedTreeChangeFamily.ts +5 -4
  389. package/src/shared-tree/treeCheckout.ts +186 -193
  390. package/src/shared-tree-core/branch.ts +93 -220
  391. package/src/shared-tree-core/branchCommitEnricher.ts +69 -64
  392. package/src/shared-tree-core/defaultResubmitMachine.ts +3 -2
  393. package/src/shared-tree-core/editManager.ts +1 -1
  394. package/src/shared-tree-core/index.ts +9 -2
  395. package/src/shared-tree-core/sharedTreeCore.ts +17 -62
  396. package/src/shared-tree-core/transaction.ts +165 -0
  397. package/src/shared-tree-core/transactionEnricher.ts +30 -24
  398. package/src/simple-tree/api/identifierIndex.ts +64 -0
  399. package/src/simple-tree/api/index.ts +5 -0
  400. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +17 -18
  401. package/src/simple-tree/api/simpleTreeIndex.ts +231 -0
  402. package/src/simple-tree/api/tree.ts +8 -5
  403. package/src/simple-tree/api/treeNodeApi.ts +1 -1
  404. package/src/simple-tree/core/index.ts +1 -0
  405. package/src/simple-tree/core/treeNodeKernel.ts +37 -2
  406. package/src/simple-tree/core/unhydratedFlexTree.ts +2 -1
  407. package/src/simple-tree/index.ts +4 -0
  408. package/src/simple-tree/objectNode.ts +19 -12
  409. package/src/simple-tree/toMapTree.ts +5 -5
  410. package/src/util/index.ts +3 -1
  411. package/src/util/typeCheck.ts +6 -1
  412. package/src/util/typeCheckTests.ts +11 -1
  413. package/src/util/utils.ts +38 -0
  414. package/dist/events/emitter.d.ts +0 -139
  415. package/dist/events/emitter.d.ts.map +0 -1
  416. package/dist/events/emitter.js +0 -165
  417. package/dist/events/emitter.js.map +0 -1
  418. package/dist/events/index.d.ts +0 -7
  419. package/dist/events/index.d.ts.map +0 -1
  420. package/dist/events/index.js +0 -11
  421. package/dist/events/index.js.map +0 -1
  422. package/dist/events/interop.d.ts +0 -30
  423. package/dist/events/interop.d.ts.map +0 -1
  424. package/dist/events/interop.js.map +0 -1
  425. package/dist/events/listeners.d.ts +0 -76
  426. package/dist/events/listeners.d.ts.map +0 -1
  427. package/dist/events/listeners.js +0 -7
  428. package/dist/events/listeners.js.map +0 -1
  429. package/dist/shared-tree-core/transactionStack.d.ts +0 -29
  430. package/dist/shared-tree-core/transactionStack.d.ts.map +0 -1
  431. package/dist/shared-tree-core/transactionStack.js +0 -41
  432. package/dist/shared-tree-core/transactionStack.js.map +0 -1
  433. package/dist/util/transactionResult.d.ts +0 -19
  434. package/dist/util/transactionResult.d.ts.map +0 -1
  435. package/dist/util/transactionResult.js +0 -23
  436. package/dist/util/transactionResult.js.map +0 -1
  437. package/lib/events/emitter.d.ts +0 -139
  438. package/lib/events/emitter.d.ts.map +0 -1
  439. package/lib/events/emitter.js +0 -160
  440. package/lib/events/emitter.js.map +0 -1
  441. package/lib/events/index.d.ts +0 -7
  442. package/lib/events/index.d.ts.map +0 -1
  443. package/lib/events/index.js.map +0 -1
  444. package/lib/events/interop.d.ts +0 -30
  445. package/lib/events/interop.d.ts.map +0 -1
  446. package/lib/events/interop.js.map +0 -1
  447. package/lib/events/listeners.d.ts +0 -76
  448. package/lib/events/listeners.d.ts.map +0 -1
  449. package/lib/events/listeners.js +0 -6
  450. package/lib/events/listeners.js.map +0 -1
  451. package/lib/shared-tree-core/transactionStack.d.ts +0 -29
  452. package/lib/shared-tree-core/transactionStack.d.ts.map +0 -1
  453. package/lib/shared-tree-core/transactionStack.js +0 -37
  454. package/lib/shared-tree-core/transactionStack.js.map +0 -1
  455. package/lib/util/transactionResult.d.ts +0 -19
  456. package/lib/util/transactionResult.d.ts.map +0 -1
  457. package/lib/util/transactionResult.js +0 -20
  458. package/lib/util/transactionResult.js.map +0 -1
  459. package/src/events/README.md +0 -3
  460. package/src/events/emitter.ts +0 -256
  461. package/src/events/index.ts +0 -19
  462. package/src/events/interop.ts +0 -38
  463. package/src/events/listeners.ts +0 -80
  464. package/src/shared-tree-core/transactionStack.ts +0 -45
  465. package/src/util/transactionResult.ts +0 -19
@@ -3,7 +3,13 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { assert, oob } from "@fluidframework/core-utils/internal";
6
+ import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
7
+ import type {
8
+ HasListeners,
9
+ IEmitter,
10
+ Listenable,
11
+ } from "@fluidframework/core-interfaces/internal";
12
+ import { createEmitter } from "@fluid-internal/client-utils";
7
13
  import type { IIdCompressor } from "@fluidframework/id-compressor";
8
14
  import {
9
15
  UsageError,
@@ -24,7 +30,6 @@ import {
24
30
  type IEditableForest,
25
31
  type IForestSubscription,
26
32
  type JsonableTree,
27
- type Revertible,
28
33
  RevertibleStatus,
29
34
  type RevisionTag,
30
35
  type RevisionTagCodec,
@@ -37,14 +42,9 @@ import {
37
42
  rootFieldKey,
38
43
  tagChange,
39
44
  visitDelta,
40
- type RevertibleFactory,
45
+ type RevertibleAlphaFactory,
46
+ type RevertibleAlpha,
41
47
  } from "../core/index.js";
42
- import {
43
- type HasListeners,
44
- type IEmitter,
45
- type Listenable,
46
- createEmitter,
47
- } from "../events/index.js";
48
48
  import {
49
49
  type FieldBatchCodec,
50
50
  type TreeCompressionStrategy,
@@ -56,10 +56,14 @@ import {
56
56
  } from "../feature-libraries/index.js";
57
57
  import {
58
58
  SharedTreeBranch,
59
+ TransactionResult,
60
+ TransactionStack,
59
61
  getChangeReplaceType,
62
+ onForkTransitive,
60
63
  type SharedTreeBranchChange,
64
+ type Transactor,
61
65
  } from "../shared-tree-core/index.js";
62
- import { Breakable, TransactionResult, disposeSymbol, fail } from "../util/index.js";
66
+ import { Breakable, disposeSymbol, fail, getLast, hasSome } from "../util/index.js";
63
67
 
64
68
  import { SharedTreeChangeFamily, hasSchemaChange } from "./sharedTreeChangeFamily.js";
65
69
  import type { SharedTreeChange } from "./sharedTreeChangeTypes.js";
@@ -72,8 +76,9 @@ import type {
72
76
  TreeViewConfiguration,
73
77
  UnsafeUnknownSchema,
74
78
  ViewableTree,
79
+ TreeBranch,
75
80
  } from "../simple-tree/index.js";
76
- import { SchematizingSimpleTreeView } from "./schematizingTreeView.js";
81
+ import { getCheckout, SchematizingSimpleTreeView } from "./schematizingTreeView.js";
77
82
 
78
83
  /**
79
84
  * Events for {@link ITreeCheckout}.
@@ -96,7 +101,17 @@ export interface CheckoutEvents {
96
101
  * @param getRevertible - a function provided that allows users to get a revertible for the change. If not provided,
97
102
  * this change is not revertible.
98
103
  */
99
- changed(data: CommitMetadata, getRevertible?: RevertibleFactory): void;
104
+ changed(data: CommitMetadata, getRevertible?: RevertibleAlphaFactory): void;
105
+
106
+ /**
107
+ * Fired when a new branch is created from this checkout.
108
+ */
109
+ fork(branch: ITreeCheckout): void;
110
+
111
+ /**
112
+ * Fired when the checkout is disposed.
113
+ */
114
+ dispose(): void;
100
115
  }
101
116
 
102
117
  /**
@@ -192,7 +207,7 @@ export interface ITreeCheckout extends AnchorLocator, ViewableTree {
192
207
  /**
193
208
  * A collection of functions for managing transactions.
194
209
  */
195
- readonly transaction: ITransaction;
210
+ readonly transaction: Transactor;
196
211
 
197
212
  branch(): ITreeCheckoutFork;
198
213
 
@@ -280,10 +295,7 @@ export function createTreeCheckout(
280
295
  );
281
296
  const events = args?.events ?? createEmitter();
282
297
 
283
- const transaction = new Transaction(branch);
284
-
285
298
  return new TreeCheckout(
286
- transaction,
287
299
  branch,
288
300
  false,
289
301
  changeFamily,
@@ -299,74 +311,6 @@ export function createTreeCheckout(
299
311
  );
300
312
  }
301
313
 
302
- /**
303
- * A collection of functions for managing transactions.
304
- * Transactions allow edits to be batched into atomic units.
305
- * Edits made during a transaction will update the local state of the tree immediately, but will be squashed into a single edit when the transaction is committed.
306
- * If the transaction is aborted, the local state will be reset to what it was before the transaction began.
307
- * Transactions may nest, meaning that a transaction may be started while a transaction is already ongoing.
308
- *
309
- * To avoid updating observers of the view state with intermediate results during a transaction,
310
- * use {@link ITreeCheckout#branch} and {@link ISharedTreeFork#merge}.
311
- */
312
- export interface ITransaction {
313
- /**
314
- * Start a new transaction.
315
- * If a transaction is already in progress when this new transaction starts, then this transaction will be "nested" inside of it,
316
- * i.e. the outer transaction will still be in progress after this new transaction is committed or aborted.
317
- *
318
- * @remarks - Asynchronous transactions are not supported on the root checkout,
319
- * since it is always kept up-to-date with the latest remote edits and the results of this rebasing (which might invalidate
320
- * the transaction) is not visible to the application author.
321
- * Instead,
322
- *
323
- * 1. fork the root checkout
324
- * 2. run the transaction on the fork
325
- * 3. merge the fork back into the root checkout
326
- *
327
- * @privateRemarks - There is currently no enforcement that asynchronous transactions don't happen on the root checkout.
328
- * AB#6488 tracks adding some enforcement to make it more clear to application authors that this is not supported.
329
- */
330
- start(): void;
331
- /**
332
- * Close this transaction by squashing its edits and committing them as a single edit.
333
- * If this is the root checkout and there are no ongoing transactions remaining, the squashed edit will be submitted to Fluid.
334
- */
335
- commit(): TransactionResult.Commit;
336
- /**
337
- * Close this transaction and revert the state of the tree to what it was before this transaction began.
338
- */
339
- abort(): TransactionResult.Abort;
340
- /**
341
- * True if there is at least one transaction currently in progress on this view, otherwise false.
342
- */
343
- inProgress(): boolean;
344
- }
345
-
346
- class Transaction implements ITransaction {
347
- public constructor(
348
- private readonly branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>,
349
- ) {}
350
-
351
- public start(): void {
352
- this.branch.startTransaction();
353
- this.branch.editor.enterTransaction();
354
- }
355
- public commit(): TransactionResult.Commit {
356
- this.branch.commitTransaction();
357
- this.branch.editor.exitTransaction();
358
- return TransactionResult.Commit;
359
- }
360
- public abort(): TransactionResult.Abort {
361
- this.branch.abortTransaction();
362
- this.branch.editor.exitTransaction();
363
- return TransactionResult.Abort;
364
- }
365
- public inProgress(): boolean {
366
- return this.branch.isTransacting();
367
- }
368
- }
369
-
370
314
  /**
371
315
  * Branch (like in a version control system) of SharedTree.
372
316
  *
@@ -401,7 +345,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
401
345
  /**
402
346
  * Set of revertibles maintained for automatic disposal
403
347
  */
404
- private readonly revertibles = new Set<DisposableRevertible>();
348
+ private readonly revertibles = new Set<RevertibleAlpha>();
405
349
 
406
350
  /**
407
351
  * Each branch's head commit corresponds to a revertible commit.
@@ -413,11 +357,6 @@ export class TreeCheckout implements ITreeCheckoutFork {
413
357
  SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>
414
358
  >();
415
359
 
416
- /**
417
- * copies of the removed roots used as snapshots for reverting to previous state when transactions are aborted
418
- */
419
- private readonly removedRootsSnapshots: DetachedFieldIndex[] = [];
420
-
421
360
  /**
422
361
  * The name of the telemetry event logged for calls to {@link TreeCheckout.revertRevertible}.
423
362
  * @privateRemarks Exposed for testing purposes.
@@ -425,7 +364,6 @@ export class TreeCheckout implements ITreeCheckoutFork {
425
364
  public static readonly revertTelemetryEventName = "RevertRevertible";
426
365
 
427
366
  public constructor(
428
- public readonly transaction: ITransaction,
429
367
  private readonly _branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>,
430
368
  /** True if and only if this checkout is for a forked branch and not the "main branch" of the tree. */
431
369
  public readonly isBranch: boolean,
@@ -447,33 +385,22 @@ export class TreeCheckout implements ITreeCheckoutFork {
447
385
  private readonly logger?: ITelemetryLoggerExt,
448
386
  private readonly breaker: Breakable = new Breakable("TreeCheckout"),
449
387
  ) {
450
- // when a transaction is started, take a snapshot of the current state of removed roots
451
- _branch.events.on("transactionStarted", () => {
452
- this.removedRootsSnapshots.push(this.removedRoots.clone());
453
- });
454
- // when a transaction is committed, the latest snapshot of removed roots can be discarded
455
- _branch.events.on("transactionCommitted", () => {
456
- this.removedRootsSnapshots.pop();
457
- });
458
- // after a transaction is rolled back, revert removed roots back to the latest snapshot
459
- _branch.events.on("transactionRolledBack", () => {
460
- const snapshot = this.removedRootsSnapshots.pop();
461
- assert(snapshot !== undefined, 0x9ae /* a snapshot for removed roots does not exist */);
462
- this.removedRoots = snapshot;
463
- });
464
-
465
388
  // We subscribe to `beforeChange` rather than `afterChange` here because it's possible that the change is invalid WRT our forest.
466
389
  // For example, a bug in the editor might produce a malformed change object and thus applying the change to the forest will throw an error.
467
390
  // In such a case we will crash here, preventing the change from being added to the commit graph, and preventing `afterChange` from firing.
468
391
  // One important consequence of this is that we will not submit the op containing the invalid change, since op submissions happens in response to `afterChange`.
469
392
  _branch.events.on("beforeChange", (event) => {
470
393
  if (event.change !== undefined) {
471
- const revision =
472
- event.type === "replace"
473
- ? // Change events will always contain new commits
474
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
475
- event.newCommits[event.newCommits.length - 1]!.revision
476
- : event.change.revision;
394
+ let revision: RevisionTag | undefined;
395
+ if (event.type === "replace") {
396
+ assert(
397
+ hasSome(event.newCommits),
398
+ 0xa81 /* Expected new commit for non no-op change event */,
399
+ );
400
+ revision = getLast(event.newCommits).revision;
401
+ } else {
402
+ revision = event.change.revision;
403
+ }
477
404
 
478
405
  // Conflicts due to schema will be empty and thus are not applied.
479
406
  for (const change of event.change.change.changes) {
@@ -505,18 +432,11 @@ export class TreeCheckout implements ITreeCheckoutFork {
505
432
  }
506
433
  this.events.emit("afterBatch");
507
434
  }
508
- if (event.type === "replace" && getChangeReplaceType(event) === "transactionCommit") {
509
- const firstCommit = event.newCommits[0] ?? oob();
510
- const transactionRevision = firstCommit.revision;
511
- for (const transactionStep of event.removedCommits) {
512
- this.removedRoots.updateMajor(transactionStep.revision, transactionRevision);
513
- }
514
- }
515
435
  });
516
436
  _branch.events.on("afterChange", (event) => {
517
437
  // The following logic allows revertibles to be generated for the change.
518
438
  // Currently only appends (including merges) and transaction commits are supported.
519
- if (!_branch.isTransacting()) {
439
+ if (!this.transaction.isInProgress()) {
520
440
  if (
521
441
  event.type === "append" ||
522
442
  (event.type === "replace" && getChangeReplaceType(event) === "transactionCommit")
@@ -529,7 +449,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
529
449
 
530
450
  const getRevertible = hasSchemaChange(change)
531
451
  ? undefined
532
- : (onRevertibleDisposed?: (revertible: Revertible) => void) => {
452
+ : (onRevertibleDisposed?: (revertible: RevertibleAlpha) => void) => {
533
453
  if (!withinEventContext) {
534
454
  throw new UsageError(
535
455
  "Cannot get a revertible outside of the context of a changed event.",
@@ -540,42 +460,12 @@ export class TreeCheckout implements ITreeCheckoutFork {
540
460
  "Cannot generate the same revertible more than once. Note that this can happen when multiple changed event listeners are registered.",
541
461
  );
542
462
  }
543
- const revertibleCommits = this.revertibleCommitBranches;
544
- const revertible: DisposableRevertible = {
545
- get status(): RevertibleStatus {
546
- const revertibleCommit = revertibleCommits.get(revision);
547
- return revertibleCommit === undefined
548
- ? RevertibleStatus.Disposed
549
- : RevertibleStatus.Valid;
550
- },
551
- revert: (release: boolean = true) => {
552
- if (revertible.status === RevertibleStatus.Disposed) {
553
- throw new UsageError(
554
- "Unable to revert a revertible that has been disposed.",
555
- );
556
- }
557
-
558
- const revertMetrics = this.revertRevertible(revision, kind);
559
- this.logger?.sendTelemetryEvent({
560
- eventName: TreeCheckout.revertTelemetryEventName,
561
- ...revertMetrics,
562
- });
563
-
564
- if (release) {
565
- revertible.dispose();
566
- }
567
- },
568
- dispose: () => {
569
- if (revertible.status === RevertibleStatus.Disposed) {
570
- throw new UsageError(
571
- "Unable to dispose a revertible that has already been disposed.",
572
- );
573
- }
574
- this.disposeRevertible(revertible, revision);
575
- onRevertibleDisposed?.(revertible);
576
- },
577
- };
578
-
463
+ const revertible = this.createRevertible(
464
+ revision,
465
+ kind,
466
+ this,
467
+ onRevertibleDisposed,
468
+ );
579
469
  this.revertibleCommitBranches.set(revision, _branch.fork(commit));
580
470
  this.revertibles.add(revertible);
581
471
  return revertible;
@@ -630,6 +520,76 @@ export class TreeCheckout implements ITreeCheckoutFork {
630
520
  }
631
521
  }
632
522
 
523
+ /**
524
+ * Creates a {@link RevertibleAlpha} object that can undo a specific change in the tree's history.
525
+ * Revision must exist in the given {@link TreeCheckout}'s branch.
526
+ *
527
+ * @param revision - The revision tag identifying the change to be made revertible.
528
+ * @param kind - The {@link CommitKind} that produced this revertible (e.g., Default, Undo, Redo).
529
+ * @param checkout - The {@link TreeCheckout} instance this revertible belongs to.
530
+ * @param onRevertibleDisposed - Callback function that will be called when the revertible is disposed.
531
+ * @returns - {@link RevertibleAlpha}
532
+ */
533
+ private createRevertible(
534
+ revision: RevisionTag,
535
+ kind: CommitKind,
536
+ checkout: TreeCheckout,
537
+ onRevertibleDisposed: ((revertible: RevertibleAlpha) => void) | undefined,
538
+ ): RevertibleAlpha {
539
+ const commitBranches = checkout.revertibleCommitBranches;
540
+
541
+ const revertible: RevertibleAlpha = {
542
+ get status(): RevertibleStatus {
543
+ const revertibleCommit = commitBranches.get(revision);
544
+ return revertibleCommit === undefined
545
+ ? RevertibleStatus.Disposed
546
+ : RevertibleStatus.Valid;
547
+ },
548
+ revert: (release: boolean = true) => {
549
+ if (revertible.status === RevertibleStatus.Disposed) {
550
+ throw new UsageError("Unable to revert a revertible that has been disposed.");
551
+ }
552
+
553
+ const revertMetrics = checkout.revertRevertible(revision, kind);
554
+ checkout.logger?.sendTelemetryEvent({
555
+ eventName: TreeCheckout.revertTelemetryEventName,
556
+ ...revertMetrics,
557
+ });
558
+
559
+ if (release) {
560
+ revertible.dispose();
561
+ }
562
+ },
563
+ clone: (forkedBranch: TreeBranch) => {
564
+ if (forkedBranch === undefined) {
565
+ return this.createRevertible(revision, kind, checkout, onRevertibleDisposed);
566
+ }
567
+
568
+ // TODO:#23442: When a revertible is cloned for a forked branch, optimize to create a fork of a revertible branch once per revision NOT once per revision per checkout.
569
+ const forkedCheckout = getCheckout(forkedBranch);
570
+ const revertibleBranch = this.revertibleCommitBranches.get(revision);
571
+ assert(
572
+ revertibleBranch !== undefined,
573
+ 0xa82 /* change to revert does not exist on the given forked branch */,
574
+ );
575
+ forkedCheckout.revertibleCommitBranches.set(revision, revertibleBranch.fork());
576
+
577
+ return this.createRevertible(revision, kind, forkedCheckout, onRevertibleDisposed);
578
+ },
579
+ dispose: () => {
580
+ if (revertible.status === RevertibleStatus.Disposed) {
581
+ throw new UsageError(
582
+ "Unable to dispose a revertible that has already been disposed.",
583
+ );
584
+ }
585
+ checkout.disposeRevertible(revertible, revision);
586
+ onRevertibleDisposed?.(revertible);
587
+ },
588
+ };
589
+
590
+ return revertible;
591
+ }
592
+
633
593
  // For the new TreeViewAlpha API
634
594
  public viewWith<TRoot extends ImplicitFieldSchema | UnsafeUnknownSchema>(
635
595
  config: TreeViewConfiguration<ReadSchema<TRoot>>,
@@ -670,6 +630,60 @@ export class TreeCheckout implements ITreeCheckoutFork {
670
630
  return this.forest.anchors.locate(anchor);
671
631
  }
672
632
 
633
+ public get transaction(): Transactor {
634
+ return this.#transaction;
635
+ }
636
+ /**
637
+ * The {@link Transactor} for this checkout.
638
+ * @remarks In the context of a checkout, transactions allow edits to be batched into atomic units.
639
+ * Edits made during a transaction will update the local state of the tree immediately, but will be squashed into a single edit when the transaction is committed.
640
+ * If the transaction is aborted, the local state will be reset to what it was before the transaction began.
641
+ * Transactions may nest, meaning that a transaction may be started while a transaction is already ongoing.
642
+ *
643
+ * To avoid updating observers of the view state with intermediate results during a transaction,
644
+ * use {@link ITreeCheckout#branch} and {@link ISharedTreeFork#merge}.
645
+ */
646
+ readonly #transaction = new TransactionStack(() => {
647
+ // Keep track of the commit that each transaction was on when it started
648
+ // TODO:#8603: This may need to be computed differently if we allow rebasing during a transaction.
649
+ const startCommit = this._branch.getHead();
650
+ // Keep track of all the forks created during the transaction so that we can dispose them when the transaction ends.
651
+ // This is a policy decision that we think is useful for the user, but it is not necessary for correctness.
652
+ const forks = new Set<TreeCheckout>();
653
+ const onDisposeUnSubscribes: (() => void)[] = [];
654
+ const onForkUnSubscribe = onForkTransitive(this, (fork) => {
655
+ forks.add(fork);
656
+ onDisposeUnSubscribes.push(fork.events.on("dispose", () => forks.delete(fork)));
657
+ });
658
+ // When each transaction is started, take a snapshot of the current state of removed roots
659
+ const removedRoots = this.removedRoots.clone();
660
+ this._branch.editor.enterTransaction();
661
+ return (result) => {
662
+ this._branch.editor.exitTransaction();
663
+ switch (result) {
664
+ case TransactionResult.Abort:
665
+ this._branch.removeAfter(startCommit);
666
+ // If a transaction is rolled back, revert removed roots back to the latest snapshot
667
+ this.removedRoots = removedRoots;
668
+ break;
669
+ case TransactionResult.Commit: {
670
+ const removedCommits = this._branch.squashAfter(startCommit);
671
+ const transactionRevision = this._branch.getHead().revision;
672
+ for (const transactionStep of removedCommits) {
673
+ this.removedRoots.updateMajor(transactionStep.revision, transactionRevision);
674
+ }
675
+ break;
676
+ }
677
+ default:
678
+ unreachableCase(result);
679
+ }
680
+
681
+ forks.forEach((fork) => fork.dispose());
682
+ onDisposeUnSubscribes.forEach((unsubscribe) => unsubscribe());
683
+ onForkUnSubscribe();
684
+ };
685
+ });
686
+
673
687
  public branch(): TreeCheckout {
674
688
  this.checkNotDisposed(
675
689
  "The parent branch has already been disposed and can no longer create new branches.",
@@ -678,9 +692,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
678
692
  const branch = this._branch.fork();
679
693
  const storedSchema = this.storedSchema.clone();
680
694
  const forest = this.forest.clone(storedSchema, anchors);
681
- const transaction = new Transaction(branch);
682
- return new TreeCheckout(
683
- transaction,
695
+ const checkout = new TreeCheckout(
684
696
  branch,
685
697
  true,
686
698
  this.changeFamily,
@@ -694,6 +706,8 @@ export class TreeCheckout implements ITreeCheckoutFork {
694
706
  this.logger,
695
707
  this.breaker,
696
708
  );
709
+ this.events.emit("fork", checkout);
710
+ return checkout;
697
711
  }
698
712
 
699
713
  public rebase(checkout: TreeCheckout): void {
@@ -704,13 +718,14 @@ export class TreeCheckout implements ITreeCheckoutFork {
704
718
  "The source of the branch rebase has been disposed and cannot be rebased.",
705
719
  );
706
720
  assert(
707
- !checkout.transaction.inProgress(),
721
+ !checkout.transaction.isInProgress(),
708
722
  0x9af /* A view cannot be rebased while it has a pending transaction */,
709
723
  );
710
724
  assert(
711
725
  checkout.isBranch,
712
726
  0xa5d /* The main branch cannot be rebased onto another branch. */,
713
727
  );
728
+
714
729
  checkout._branch.rebaseOnto(this._branch);
715
730
  }
716
731
 
@@ -731,10 +746,10 @@ export class TreeCheckout implements ITreeCheckoutFork {
731
746
  "The source of the branch merge has been disposed and cannot be merged.",
732
747
  );
733
748
  assert(
734
- !this.transaction.inProgress(),
749
+ !this.transaction.isInProgress(),
735
750
  0x9b0 /* Views cannot be merged into a view while it has a pending transaction */,
736
751
  );
737
- while (checkout.transaction.inProgress()) {
752
+ while (checkout.transaction.isInProgress()) {
738
753
  checkout.transaction.commit();
739
754
  }
740
755
  this._branch.merge(checkout._branch);
@@ -758,11 +773,13 @@ export class TreeCheckout implements ITreeCheckoutFork {
758
773
  "The branch has already been disposed and cannot be disposed again.",
759
774
  );
760
775
  this.disposed = true;
776
+ this.#transaction.dispose();
761
777
  this.purgeRevertibles();
762
778
  this._branch.dispose();
763
779
  for (const view of this.views) {
764
780
  view.dispose();
765
781
  }
782
+ this.events.emit("dispose");
766
783
  }
767
784
 
768
785
  public getRemovedRoots(): [string | number | undefined, number, JsonableTree][] {
@@ -796,14 +813,14 @@ export class TreeCheckout implements ITreeCheckoutFork {
796
813
  }
797
814
  }
798
815
 
799
- private disposeRevertible(revertible: DisposableRevertible, revision: RevisionTag): void {
816
+ private disposeRevertible(revertible: RevertibleAlpha, revision: RevisionTag): void {
800
817
  this.revertibleCommitBranches.get(revision)?.dispose();
801
818
  this.revertibleCommitBranches.delete(revision);
802
819
  this.revertibles.delete(revertible);
803
820
  }
804
821
 
805
822
  private revertRevertible(revision: RevisionTag, kind: CommitKind): RevertMetrics {
806
- if (this._branch.isTransacting()) {
823
+ if (this.transaction.isInProgress()) {
807
824
  throw new UsageError("Undo is not yet supported during transactions.");
808
825
  }
809
826
 
@@ -880,36 +897,12 @@ export class TreeCheckout implements ITreeCheckoutFork {
880
897
  */
881
898
  private isRemoteChangeEvent(event: SharedTreeBranchChange<SharedTreeChange>): boolean {
882
899
  return (
883
- // remote changes are only ever applied to the main branch
900
+ // Remote changes are only ever applied to the main branch
884
901
  !this.isBranch &&
885
- // remote changes are applied to the main branch by rebasing it onto the trunk,
886
- // no other rebases are allowed on the main branch so this means any replaces that are not
887
- // transaction commits are remote changes
902
+ // Remote changes are applied to the main branch by rebasing it onto the trunk.
903
+ // No other rebases are allowed on the main branch, so we can use this to detect remote changes.
888
904
  event.type === "replace" &&
889
- getChangeReplaceType(event) !== "transactionCommit"
905
+ getChangeReplaceType(event) === "rebase"
890
906
  );
891
907
  }
892
908
  }
893
-
894
- /**
895
- * Run a synchronous transaction on the given shared tree view.
896
- * This is a convenience helper around the {@link SharedTreeFork#transaction} APIs.
897
- * @param view - the view on which to run the transaction
898
- * @param transaction - the transaction function. This will be executed immediately. It is passed `view` as an argument for convenience.
899
- * If this function returns an `Abort` result then the transaction will be aborted. Otherwise, it will be committed.
900
- * @returns whether or not the transaction was committed or aborted
901
- */
902
- export function runSynchronous(
903
- view: ITreeCheckout,
904
- transaction: (view: ITreeCheckout) => TransactionResult | void,
905
- ): TransactionResult {
906
- view.transaction.start();
907
- const result = transaction(view);
908
- return result === TransactionResult.Abort
909
- ? view.transaction.abort()
910
- : view.transaction.commit();
911
- }
912
-
913
- interface DisposableRevertible extends Revertible {
914
- dispose: () => void;
915
- }