@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,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { assert, oob } from "@fluidframework/core-utils/internal";
6
+ import { assert } from "@fluidframework/core-utils/internal";
7
7
  import { type TelemetryEventBatcher, measure } from "@fluidframework/telemetry-utils/internal";
8
8
 
9
9
  import {
@@ -21,10 +21,10 @@ import {
21
21
  tagRollbackInverse,
22
22
  type RebaseStatsWithDuration,
23
23
  } from "../core/index.js";
24
- import { createEmitter, type Listenable } from "../events/index.js";
24
+ import type { Listenable } from "@fluidframework/core-interfaces";
25
+ import { createEmitter } from "@fluid-internal/client-utils";
25
26
 
26
- import { TransactionStack } from "./transactionStack.js";
27
- import { fail } from "../util/index.js";
27
+ import { hasSome } from "../util/index.js";
28
28
 
29
29
  /**
30
30
  * Describes a change to a `SharedTreeBranch`. Various operations can mutate the head of the branch;
@@ -46,12 +46,12 @@ export type SharedTreeBranchChange<TChange> =
46
46
  type: "append";
47
47
  kind: CommitKind;
48
48
  change: TaggedChange<TChange>;
49
- newCommits: readonly GraphCommit<TChange>[];
49
+ newCommits: readonly [GraphCommit<TChange>, ...GraphCommit<TChange>[]];
50
50
  }
51
51
  | {
52
52
  type: "remove";
53
53
  change: TaggedChange<TChange> | undefined;
54
- removedCommits: readonly GraphCommit<TChange>[];
54
+ removedCommits: readonly [GraphCommit<TChange>, ...GraphCommit<TChange>[]];
55
55
  }
56
56
  | {
57
57
  type: "replace";
@@ -125,34 +125,6 @@ export interface SharedTreeBranchEvents<TEditor extends ChangeFamilyEditor, TCha
125
125
  * Fired after this branch is disposed
126
126
  */
127
127
  dispose(): void;
128
-
129
- /**
130
- * Fired after a new transaction is started.
131
- * @param isOuterTransaction - true iff the transaction being started is the outermost transaction
132
- * as opposed to a nested transaction.
133
- */
134
- transactionStarted(isOuterTransaction: boolean): void;
135
-
136
- /**
137
- * Fired after the current transaction is aborted.
138
- * @param isOuterTransaction - true iff the transaction being aborted is the outermost transaction
139
- * as opposed to a nested transaction.
140
- */
141
- transactionAborted(isOuterTransaction: boolean): void;
142
-
143
- /**
144
- * Fired after the current transaction is completely rolled back.
145
- * @param isOuterTransaction - true iff the transaction being aborted is the outermost transaction
146
- * as opposed to a nested transaction.
147
- */
148
- transactionRolledBack(isOuterTransaction: boolean): void;
149
-
150
- /**
151
- * Fired after the current transaction is committed.
152
- * @param isOuterTransaction - true iff the transaction being committed is the outermost transaction
153
- * as opposed to a nested transaction.
154
- */
155
- transactionCommitted(isOuterTransaction: boolean): void;
156
128
  }
157
129
 
158
130
  /**
@@ -179,30 +151,6 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
179
151
  readonly #events = createEmitter<SharedTreeBranchEvents<TEditor, TChange>>();
180
152
  public readonly events: Listenable<SharedTreeBranchEvents<TEditor, TChange>> = this.#events;
181
153
  public readonly editor: TEditor;
182
- private readonly transactions = new TransactionStack();
183
- /**
184
- * After pushing a starting revision to the transaction stack, this branch might be rebased
185
- * over commits which are children of that starting revision. When the transaction is committed,
186
- * those rebased-over commits should not be included in the transaction's squash commit, even though
187
- * they exist between the starting revision and the final commit within the transaction.
188
- *
189
- * Whenever `rebaseOnto` is called during a transaction, this map is augmented with an entry from the
190
- * original merge-base to the new merge-base.
191
- *
192
- * This state need only be retained for the lifetime of the transaction.
193
- *
194
- * TODO: This strategy might need to be revisited when adding better support for async transactions.
195
- * Since:
196
- *
197
- * 1. Transactionality is guaranteed primarily by squashing at commit time
198
- * 2. Branches may be rebased with an ongoing transaction
199
- *
200
- * a rebase operation might invalidate only a portion of a transaction's commits, thus defeating the
201
- * purpose of transactionality.
202
- *
203
- * AB#6483 and children items track this work.
204
- */
205
- private readonly initialTransactionRevToRebasedRev = new Map<RevisionTag, RevisionTag>();
206
154
  private disposed = false;
207
155
  private readonly unsubscribeBranchTrimmer?: () => void;
208
156
  /**
@@ -230,11 +178,12 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
230
178
  }
231
179
 
232
180
  /**
233
- * Sets the head of this branch. Emits no change events.
181
+ * Sets the head of this branch.
182
+ * @remarks This is a "manual override" of sorts, for when the branch needs to be set to a certain state without going through the usual flow of edits.
183
+ * This might be necessary as a performance optimization, or to prevent parts of the system updating incorrectly (this method emits no change events!).
234
184
  */
235
185
  public setHead(head: GraphCommit<TChange>): void {
236
186
  this.assertNotDisposed();
237
- assert(!this.isTransacting(), 0x685 /* Cannot set head during a transaction */);
238
187
  this.head = head;
239
188
  }
240
189
 
@@ -278,147 +227,6 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
278
227
  return this.head;
279
228
  }
280
229
 
281
- /**
282
- * Begin a transaction on this branch. If the transaction is committed via {@link commitTransaction},
283
- * all commits made since this call will be squashed into a single head commit.
284
- */
285
- public startTransaction(): void {
286
- this.assertNotDisposed();
287
- const forks = new Set<SharedTreeBranch<TEditor, TChange>>();
288
- const onDisposeUnSubscribes: (() => void)[] = [];
289
- const onForkUnSubscribe = onForkTransitive(this, (fork) => {
290
- forks.add(fork);
291
- onDisposeUnSubscribes.push(fork.events.on("dispose", () => forks.delete(fork)));
292
- });
293
- this.transactions.push(this.head.revision, () => {
294
- forks.forEach((fork) => fork.dispose());
295
- onDisposeUnSubscribes.forEach((unsubscribe) => unsubscribe());
296
- onForkUnSubscribe();
297
- });
298
- this.editor.enterTransaction();
299
- this.#events.emit("transactionStarted", this.transactions.size === 1);
300
- }
301
-
302
- /**
303
- * Commit the current transaction. There must be a transaction in progress that was begun via {@link startTransaction}.
304
- * If there are commits in the current transaction, they will be squashed into a new single head commit.
305
- * @returns the commits that were squashed and the new squash commit if a squash occurred, otherwise `undefined`.
306
- * @remarks If the transaction had no changes applied during its lifetime, then no squash occurs (i.e. this method is a no-op).
307
- * Even if the transaction contained only one change, it will still be replaced with an (equivalent) squash change.
308
- */
309
- public commitTransaction():
310
- | [squashedCommits: GraphCommit<TChange>[], newCommit: GraphCommit<TChange>]
311
- | undefined {
312
- this.assertNotDisposed();
313
- const [startCommit, commits] = this.popTransaction();
314
- this.editor.exitTransaction();
315
-
316
- this.#events.emit("transactionCommitted", this.transactions.size === 0);
317
- if (commits.length === 0) {
318
- return undefined;
319
- }
320
-
321
- // Squash the changes and make the squash commit the new head of this branch
322
- const squashedChange = this.changeFamily.rebaser.compose(commits);
323
- const revision = this.mintRevisionTag();
324
-
325
- const newHead = mintCommit(startCommit, {
326
- revision,
327
- change: this.changeFamily.rebaser.changeRevision(squashedChange, revision),
328
- });
329
-
330
- const changeEvent = {
331
- type: "replace",
332
- change: undefined,
333
- removedCommits: commits,
334
- newCommits: [newHead],
335
- } as const;
336
-
337
- this.#events.emit("beforeChange", changeEvent);
338
- this.head = newHead;
339
- this.#events.emit("afterChange", changeEvent);
340
- return [commits, newHead];
341
- }
342
-
343
- /**
344
- * Cancel the current transaction. There must be a transaction in progress that was begun via
345
- * {@link startTransaction}. All commits made during the transaction will be removed.
346
- * @returns the change to this branch resulting in the removal of the commits, and a list of the
347
- * commits that were removed.
348
- */
349
- public abortTransaction(): [
350
- change: TChange | undefined,
351
- abortedCommits: GraphCommit<TChange>[],
352
- ] {
353
- this.assertNotDisposed();
354
- const [startCommit, commits] = this.popTransaction();
355
- this.editor.exitTransaction();
356
-
357
- this.#events.emit("transactionAborted", this.transactions.size === 0);
358
- if (commits.length === 0) {
359
- this.#events.emit("transactionRolledBack", this.transactions.size === 0);
360
- return [undefined, []];
361
- }
362
-
363
- const inverses: TaggedChange<TChange>[] = [];
364
- for (let i = commits.length - 1; i >= 0; i--) {
365
- const revision = this.mintRevisionTag();
366
- const commit =
367
- commits[i] ?? fail("This wont run because we are iterating through commits");
368
- const inverse = this.changeFamily.rebaser.changeRevision(
369
- this.changeFamily.rebaser.invert(commit, true, revision),
370
- revision,
371
- commit.revision,
372
- );
373
-
374
- inverses.push(tagRollbackInverse(inverse, revision, commit.revision));
375
- }
376
- const change =
377
- inverses.length > 0 ? this.changeFamily.rebaser.compose(inverses) : undefined;
378
-
379
- const changeEvent = {
380
- type: "remove",
381
- change: change === undefined ? undefined : makeAnonChange(change),
382
- removedCommits: commits,
383
- } as const;
384
-
385
- this.#events.emit("beforeChange", changeEvent);
386
- this.head = startCommit;
387
- this.#events.emit("afterChange", changeEvent);
388
- this.#events.emit("transactionRolledBack", this.transactions.size === 0);
389
- return [change, commits];
390
- }
391
-
392
- /**
393
- * True iff this branch is in the middle of a transaction that was begin via {@link startTransaction}
394
- */
395
- public isTransacting(): boolean {
396
- return this.transactions.size !== 0;
397
- }
398
-
399
- private popTransaction(): [GraphCommit<TChange>, GraphCommit<TChange>[]] {
400
- const { startRevision: startRevisionOriginal } = this.transactions.pop();
401
- let startRevision = startRevisionOriginal;
402
- while (this.initialTransactionRevToRebasedRev.has(startRevision)) {
403
- startRevision = this.initialTransactionRevToRebasedRev.get(startRevision) ?? oob();
404
- }
405
-
406
- if (!this.isTransacting()) {
407
- this.initialTransactionRevToRebasedRev.clear();
408
- }
409
-
410
- const commits: GraphCommit<TChange>[] = [];
411
- const startCommit = findAncestor(
412
- [this.head, commits],
413
- (c) => c.revision === startRevision,
414
- );
415
- assert(
416
- startCommit !== undefined,
417
- 0x593 /* Expected branch to be ahead of transaction start revision */,
418
- );
419
- return [startCommit, commits];
420
- }
421
-
422
230
  /**
423
231
  * Spawn a new branch that is based off of the current state of this branch.
424
232
  * @param commit - The commit to base the new branch off of. Defaults to the head of this branch.
@@ -460,17 +268,9 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
460
268
  // The net change to this branch is provided by the `rebaseBranch` API
461
269
  const { newSourceHead, commits } = rebaseResult;
462
270
  const { deletedSourceCommits, targetCommits, sourceCommits } = commits;
271
+ assert(hasSome(targetCommits), 0xa83 /* Expected commit(s) for a non no-op rebase */);
463
272
 
464
273
  const newCommits = targetCommits.concat(sourceCommits);
465
- if (this.isTransacting()) {
466
- const firstCommit = targetCommits[0] ?? oob();
467
- const lastCommit = targetCommits[targetCommits.length - 1] ?? oob();
468
- const src = firstCommit.parent?.revision;
469
- const dst = lastCommit.revision;
470
- if (src !== undefined && dst !== undefined) {
471
- this.initialTransactionRevToRebasedRev.set(src, dst);
472
- }
473
- }
474
274
  const changeEvent = {
475
275
  type: "replace",
476
276
  get change() {
@@ -487,6 +287,87 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
487
287
  return rebaseResult;
488
288
  }
489
289
 
290
+ /**
291
+ * Remove a range of commits from this branch.
292
+ * @param commit - All commits after (but not including) this commit will be removed.
293
+ * @returns The net change to this branch and the commits that were removed from this branch.
294
+ */
295
+ public removeAfter(
296
+ commit: GraphCommit<TChange>,
297
+ ): [change: TaggedChange<TChange> | undefined, removedCommits: GraphCommit<TChange>[]] {
298
+ if (commit === this.head) {
299
+ return [undefined, []];
300
+ }
301
+
302
+ const removedCommits: GraphCommit<TChange>[] = [];
303
+ const inverses: TaggedChange<TChange>[] = [];
304
+ findAncestor([this.head, removedCommits], (c) => {
305
+ // TODO: Pull this side effect out if/when more diverse ancestry walking helpers are available
306
+ if (c !== commit) {
307
+ const revision = this.mintRevisionTag();
308
+ const inverse = this.changeFamily.rebaser.changeRevision(
309
+ this.changeFamily.rebaser.invert(c, true, revision),
310
+ revision,
311
+ c.revision,
312
+ );
313
+
314
+ inverses.push(tagRollbackInverse(inverse, revision, c.revision));
315
+ return false;
316
+ }
317
+
318
+ return true;
319
+ });
320
+ assert(hasSome(removedCommits), 0xa84 /* Commit must be in the branch's ancestry */);
321
+
322
+ const change = makeAnonChange(this.changeFamily.rebaser.compose(inverses));
323
+ const changeEvent = {
324
+ type: "remove",
325
+ change,
326
+ removedCommits,
327
+ } as const;
328
+
329
+ this.#events.emit("beforeChange", changeEvent);
330
+ this.head = commit;
331
+ this.#events.emit("afterChange", changeEvent);
332
+ return [change, removedCommits];
333
+ }
334
+
335
+ /**
336
+ * Replace a range of commits on this branch with a single commit composed of equivalent changes.
337
+ * @param commit - All commits after (but not including) this commit will be squashed.
338
+ * @returns The commits that were squashed and removed from this branch.
339
+ * @remarks The commits after `commit` will be removed from this branch, and the squash commit will become the new head of this branch.
340
+ * The change event emitted by this operation will have a `change` property that is undefined, since no net change occurred.
341
+ */
342
+ public squashAfter(commit: GraphCommit<TChange>): GraphCommit<TChange>[] {
343
+ if (commit === this.head) {
344
+ return [];
345
+ }
346
+
347
+ const removedCommits: GraphCommit<TChange>[] = [];
348
+ findAncestor([this.head, removedCommits], (c) => c === commit);
349
+ assert(hasSome(removedCommits), 0xa85 /* Commit must be in the branch's ancestry */);
350
+
351
+ const squashedChange = this.changeFamily.rebaser.compose(removedCommits);
352
+ const revision = this.mintRevisionTag();
353
+ const newHead = mintCommit(commit, {
354
+ revision,
355
+ change: this.changeFamily.rebaser.changeRevision(squashedChange, revision),
356
+ });
357
+
358
+ const changeEvent = {
359
+ type: "replace",
360
+ change: undefined,
361
+ removedCommits,
362
+ newCommits: [newHead],
363
+ } as const;
364
+
365
+ this.#events.emit("beforeChange", changeEvent);
366
+ this.head = newHead;
367
+ this.#events.emit("afterChange", changeEvent);
368
+ return removedCommits;
369
+ }
370
+
490
371
  /**
491
372
  * Apply all the divergent changes on the given branch to this branch.
492
373
  *
@@ -499,10 +380,6 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
499
380
  ): [change: TChange, newCommits: GraphCommit<TChange>[]] | undefined {
500
381
  this.assertNotDisposed();
501
382
  branch.assertNotDisposed();
502
- assert(
503
- !branch.isTransacting(),
504
- 0x597 /* Branch may not be merged while transaction is in progress */,
505
- );
506
383
 
507
384
  if (branch === this) {
508
385
  return undefined;
@@ -516,6 +393,7 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
516
393
 
517
394
  // Compute the net change to this branch
518
395
  const sourceCommits = rebaseResult.commits.sourceCommits;
396
+ assert(hasSome(sourceCommits), 0xa86 /* Expected source commits in non no-op merge */);
519
397
  const change = this.changeFamily.rebaser.compose(sourceCommits);
520
398
  const taggedChange = makeAnonChange(change);
521
399
  const changeEvent = {
@@ -576,10 +454,6 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
576
454
  return;
577
455
  }
578
456
 
579
- while (this.isTransacting()) {
580
- this.abortTransaction();
581
- }
582
-
583
457
  this.unsubscribeBranchTrimmer?.();
584
458
 
585
459
  this.disposed = true;
@@ -600,8 +474,7 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
600
474
  * The deregister function has undefined behavior if called more than once.
601
475
  */
602
476
  // Branches are invariant over TChange
603
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
604
- export function onForkTransitive<T extends SharedTreeBranch<ChangeFamilyEditor, any>>(
477
+ export function onForkTransitive<T extends { events: Listenable<{ fork(t: T): void }> }>(
605
478
  branch: T,
606
479
  onFork: (fork: T) => void,
607
480
  ): () => void {
@@ -4,106 +4,111 @@
4
4
  */
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
- import { type ChangeRebaser, type GraphCommit, replaceChange } from "../core/index.js";
7
+ import {
8
+ type ChangeRebaser,
9
+ type GraphCommit,
10
+ replaceChange,
11
+ type RevisionTag,
12
+ } from "../core/index.js";
8
13
  import type { ChangeEnricherReadonlyCheckout } from "./changeEnricher.js";
9
14
  import { TransactionEnricher } from "./transactionEnricher.js";
15
+ import { getChangeReplaceType, type SharedTreeBranchChange } from "./branch.js";
10
16
 
11
17
  /**
12
18
  * Utility for enriching commits from a {@link Branch} before these commits are applied and submitted.
13
19
  */
14
20
  export class BranchCommitEnricher<TChange> {
15
- private readonly transactionEnricher: TransactionEnricher<TChange>;
16
- private readonly enricher: ChangeEnricherReadonlyCheckout<TChange>;
21
+ readonly #transactionEnricher: TransactionEnricher<TChange>;
22
+ readonly #enricher: ChangeEnricherReadonlyCheckout<TChange>;
17
23
  /**
18
24
  * Maps each local commit to the corresponding enriched commit.
19
- * Entries are added when the commits are prepared (before being applied and submitted).
20
- * Entries are removed when the commits are retrieved for submission (after being applied).
21
- * It's possible an entry will linger in the map indefinitely if it is never retrieved for submission.
22
- * This would happen if applying a commit were to fail and the commit were not retrieved/purged after the failure.
25
+ * @remarks
26
+ * Entries are added when the commits are {@link BranchCommitEnricher.processChange | processed during a change}.
27
+ * Each entry is removed when it is {@link BranchCommitEnricher.enrich | retrieved}.
28
+ * In the event that an entry is not explicitly removed, it will eventually be {@link WeakMap | dropped from memory} along with the associated commit.
23
29
  */
24
- private readonly preparedCommits: Map<GraphCommit<TChange>, GraphCommit<TChange>> =
25
- new Map();
30
+ readonly #preparedCommits: WeakMap<GraphCommit<TChange>, GraphCommit<TChange>> = new Map();
31
+
32
+ /**
33
+ * If defined, a top-level transaction has been {@link BranchCommitEnricher.commitTransaction | committed} since the last {@link BranchCommitEnricher.processChange | change has been processed}.
34
+ * Calling this function will compute the composition of that transaction's commits.
35
+ * @remarks This function will be reset to undefined after each {@link BranchCommitEnricher.processChange | change is processed}.
36
+ */
37
+ #getOuterTransactionChange?: (revision: RevisionTag) => TChange;
26
38
 
27
39
  public constructor(
28
40
  rebaser: ChangeRebaser<TChange>,
29
41
  enricher: ChangeEnricherReadonlyCheckout<TChange>,
30
42
  ) {
31
- this.enricher = enricher;
32
- this.transactionEnricher = new TransactionEnricher(rebaser, this.enricher);
43
+ this.#enricher = enricher;
44
+ this.#transactionEnricher = new TransactionEnricher(rebaser, this.#enricher);
33
45
  }
34
46
 
35
47
  /**
36
- * @returns The number of commits that have been prepared but not yet retrieved.
48
+ * Process the given change, preparing new commits for {@link BranchCommitEnricher.enrich | enrichment}.
49
+ * @param change - The change to process.
50
+ * @param isAttached - Whether or not the SharedTree is attached to the service.
37
51
  */
38
- public get preparedCommitsCount(): number {
39
- return this.preparedCommits.size;
40
- }
41
-
42
- public startNewTransaction(): void {
43
- this.transactionEnricher.startNewTransaction();
44
- }
52
+ public processChange(change: SharedTreeBranchChange<TChange>): void {
53
+ if (this.#transactionEnricher.isTransacting()) {
54
+ if (change.type === "append") {
55
+ for (const commit of change.newCommits) {
56
+ // We do not submit ops for changes that are part of a transaction.
57
+ // But we need to enrich the commits that will be sent if the transaction is committed.
58
+ this.#transactionEnricher.addTransactionStep(commit);
59
+ }
60
+ }
61
+ } else {
62
+ if (
63
+ change.type === "append" ||
64
+ (change.type === "replace" && getChangeReplaceType(change) === "transactionCommit")
65
+ ) {
66
+ for (const newCommit of change.newCommits) {
67
+ const newChange =
68
+ this.#getOuterTransactionChange?.(newCommit.revision) ??
69
+ this.#enricher.updateChangeEnrichments(newCommit.change, newCommit.revision);
45
70
 
46
- public commitCurrentTransaction(): void {
47
- this.transactionEnricher.commitCurrentTransaction();
48
- }
71
+ this.#preparedCommits.set(newCommit, replaceChange(newCommit, newChange));
72
+ }
73
+ }
74
+ }
49
75
 
50
- public abortCurrentTransaction(): void {
51
- this.transactionEnricher.abortCurrentTransaction();
76
+ this.#getOuterTransactionChange = undefined;
52
77
  }
53
78
 
54
79
  /**
55
- * Adds a commit to the enricher.
56
- * @param commit - A commit that is part of a transaction.
80
+ * Retrieves the enriched version of the given commit.
81
+ * @param commit - A commit {@link BranchCommitEnricher.processChange | processed during the most recent change}.
82
+ * @remarks A commit can only be enriched once - subsequent calls to this method with the same commit will throw an error.
57
83
  */
58
- public ingestTransactionCommit(commit: GraphCommit<TChange>): void {
59
- // We do not submit ops for changes that are part of a transaction.
60
- // But we need to enrich the commits that will be sent if the transaction is committed.
61
- this.transactionEnricher.addTransactionStep(commit);
84
+ public enrich(commit: GraphCommit<TChange>): GraphCommit<TChange> {
85
+ const prepared = this.#preparedCommits.get(commit);
86
+ assert(prepared !== undefined, 0x980 /* Unknown commit */);
87
+ this.#preparedCommits.delete(commit);
88
+ return prepared;
62
89
  }
63
90
 
64
91
  /**
65
- * Prepares an enriched commit for later submission (see {@link BranchCommitEnricher.getPreparedCommit}).
66
- * @param commit - The commit to prepare an enriched version of.
67
- * @param concludesOuterTransaction - Whether the commit concludes an outer transaction.
68
- *
69
- * Each call to this method must be followed by a call to {@link BranchCommitEnricher.getPreparedCommit} or
70
- * {@link BranchCommitEnricher.purgePreparedCommits}. Failing to do so will result in a memory leak.
92
+ * Notify the enricher that a new transaction has started.
93
+ * @remarks This may be called multiple times without calling {@link BranchCommitEnricher.commitTransaction | commitTransaction}, producing "nested transactions".
71
94
  */
72
- public prepareCommit(
73
- commit: GraphCommit<TChange>,
74
- concludesOuterTransaction: boolean,
75
- ): void {
76
- let enrichedChange: TChange;
77
- if (concludesOuterTransaction) {
78
- assert(
79
- this.transactionEnricher !== undefined,
80
- 0x97f /* Unexpected transaction commit without transaction steps */,
81
- );
82
- enrichedChange = this.transactionEnricher.getComposedChange(commit.revision);
83
- } else {
84
- enrichedChange = this.enricher.updateChangeEnrichments(commit.change, commit.revision);
85
- }
86
- this.preparedCommits.set(commit, replaceChange(commit, enrichedChange));
95
+ public startTransaction(): void {
96
+ this.#transactionEnricher.startTransaction();
87
97
  }
88
98
 
89
99
  /**
90
- * @param commit - A commit previously passed to {@link BranchCommitEnricher.prepareCommit}.
91
- * @returns The enriched commit corresponds to the given commit.
100
+ * Commit the current transaction.
101
+ * @remarks This should be called _before_ the corresponding transaction commit change is {@link BranchCommitEnricher.processChange | processed}.
92
102
  */
93
- public getPreparedCommit(commit: GraphCommit<TChange>): GraphCommit<TChange> {
94
- const prepared = this.preparedCommits.get(commit);
95
- assert(prepared !== undefined, 0x980 /* Unknown commit */);
96
- this.preparedCommits.delete(commit);
97
- return prepared;
103
+ public commitTransaction(): void {
104
+ this.#getOuterTransactionChange = this.#transactionEnricher.commitTransaction();
98
105
  }
99
106
 
100
107
  /**
101
- * Purges all commits that have been prepared but not been retrieved.
102
- * This should be called to avoid memory leaks if the prepared commits are no longer needed.
103
- *
104
- * Does not affect ingested transaction commits.
108
+ * Notify the enricher that the current transaction has been aborted.
109
+ * @remarks This will throw an error if there is no ongoing transaction.
105
110
  */
106
- public purgePreparedCommits(): void {
107
- this.preparedCommits.clear();
111
+ public abortTransaction(): void {
112
+ this.#transactionEnricher.abortTransaction();
108
113
  }
109
114
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { assert, oob } from "@fluidframework/core-utils/internal";
7
7
  import type { GraphCommit, TaggedChange } from "../core/index.js";
8
- import { disposeSymbol } from "../util/index.js";
8
+ import { disposeSymbol, hasSome } from "../util/index.js";
9
9
  import type { ChangeEnricherReadonlyCheckout, ResubmitMachine } from "./index.js";
10
10
 
11
11
  /**
@@ -114,7 +114,8 @@ export class DefaultResubmitMachine<TChange> implements ResubmitMachine<TChange>
114
114
  this.isInResubmitPhase,
115
115
  0x982 /* No available commit to resubmit outside of resubmit phase */,
116
116
  );
117
- return this.resubmitQueue[0] ?? oob();
117
+ assert(hasSome(this.resubmitQueue), 0xa87 /* Expected resubmit queue to be non-empty */);
118
+ return this.resubmitQueue[0];
118
119
  }
119
120
 
120
121
  public get isInResubmitPhase(): boolean {
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
+ import { createEmitter } from "@fluid-internal/client-utils";
7
8
  import type { SessionId } from "@fluidframework/id-compressor";
8
9
  import { BTree } from "@tylerbu/sorted-btree-es6";
9
10
 
@@ -41,7 +42,6 @@ import {
41
42
  minSequenceId,
42
43
  sequenceIdComparator,
43
44
  } from "./sequenceIdUtils.js";
44
- import { createEmitter } from "../events/index.js";
45
45
  import {
46
46
  TelemetryEventBatcher,
47
47
  measure,
@@ -11,6 +11,15 @@ export {
11
11
  getChangeReplaceType,
12
12
  } from "./branch.js";
13
13
 
14
+ export {
15
+ TransactionResult,
16
+ type Transactor,
17
+ type TransactionEvents,
18
+ TransactionStack,
19
+ type OnPush,
20
+ type OnPop,
21
+ } from "./transaction.js";
22
+
14
23
  export {
15
24
  type ExplicitCoreCodecVersions,
16
25
  SharedTreeCore,
@@ -28,8 +37,6 @@ export {
28
37
  NoOpChangeEnricher,
29
38
  } from "./changeEnricher.js";
30
39
 
31
- export { TransactionStack } from "./transactionStack.js";
32
-
33
40
  export { makeEditManagerCodec } from "./editManagerCodecs.js";
34
41
  export { EditManagerSummarizer } from "./editManagerSummarizer.js";
35
42
  export {