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