@fluidframework/tree 2.11.0 → 2.12.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 (537) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-report/tree.alpha.api.md +2 -2
  3. package/api-report/tree.beta.api.md +1 -1
  4. package/api-report/tree.legacy.alpha.api.md +1 -1
  5. package/api-report/tree.legacy.public.api.md +1 -1
  6. package/api-report/tree.public.api.md +1 -1
  7. package/dist/core/index.d.ts +2 -2
  8. package/dist/core/index.d.ts.map +1 -1
  9. package/dist/core/index.js +5 -3
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/core/rebase/utils.d.ts.map +1 -1
  12. package/dist/core/rebase/utils.js +2 -9
  13. package/dist/core/rebase/utils.js.map +1 -1
  14. package/dist/core/schema-stored/format.d.ts +0 -3
  15. package/dist/core/schema-stored/format.d.ts.map +1 -1
  16. package/dist/core/schema-stored/format.js.map +1 -1
  17. package/dist/core/schema-stored/schema.d.ts +12 -10
  18. package/dist/core/schema-stored/schema.d.ts.map +1 -1
  19. package/dist/core/schema-stored/schema.js +3 -5
  20. package/dist/core/schema-stored/schema.js.map +1 -1
  21. package/dist/core/schema-view/index.d.ts +1 -1
  22. package/dist/core/schema-view/index.d.ts.map +1 -1
  23. package/dist/core/schema-view/index.js +1 -2
  24. package/dist/core/schema-view/index.js.map +1 -1
  25. package/dist/core/schema-view/view.d.ts +0 -7
  26. package/dist/core/schema-view/view.d.ts.map +1 -1
  27. package/dist/core/schema-view/view.js +1 -12
  28. package/dist/core/schema-view/view.js.map +1 -1
  29. package/dist/{feature-libraries/chunked-forest → core/tree}/chunk.d.ts +2 -1
  30. package/dist/core/tree/chunk.d.ts.map +1 -0
  31. package/dist/{feature-libraries/chunked-forest → core/tree}/chunk.js +2 -2
  32. package/dist/core/tree/chunk.js.map +1 -0
  33. package/dist/core/tree/index.d.ts +1 -0
  34. package/dist/core/tree/index.d.ts.map +1 -1
  35. package/dist/core/tree/index.js +5 -1
  36. package/dist/core/tree/index.js.map +1 -1
  37. package/dist/core/tree/treeTextFormat.d.ts +0 -5
  38. package/dist/core/tree/treeTextFormat.d.ts.map +1 -1
  39. package/dist/core/tree/treeTextFormat.js.map +1 -1
  40. package/dist/core/tree/types.d.ts +0 -5
  41. package/dist/core/tree/types.d.ts.map +1 -1
  42. package/dist/core/tree/types.js +0 -1
  43. package/dist/core/tree/types.js.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +1 -2
  45. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  46. package/dist/feature-libraries/chunked-forest/basicChunk.js +14 -14
  47. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  48. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +1 -2
  49. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  50. package/dist/feature-libraries/chunked-forest/chunkTree.js +2 -3
  51. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  52. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -2
  53. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  54. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  55. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.d.ts +1 -2
  56. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.d.ts.map +1 -1
  57. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
  58. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +1 -2
  59. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  60. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  61. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +1 -1
  62. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  63. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  64. package/dist/feature-libraries/chunked-forest/emptyChunk.d.ts +1 -1
  65. package/dist/feature-libraries/chunked-forest/emptyChunk.d.ts.map +1 -1
  66. package/dist/feature-libraries/chunked-forest/emptyChunk.js +2 -3
  67. package/dist/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
  68. package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
  69. package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  70. package/dist/feature-libraries/chunked-forest/index.js +5 -5
  71. package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
  72. package/dist/feature-libraries/chunked-forest/sequenceChunk.d.ts +1 -1
  73. package/dist/feature-libraries/chunked-forest/sequenceChunk.d.ts.map +1 -1
  74. package/dist/feature-libraries/chunked-forest/sequenceChunk.js +2 -2
  75. package/dist/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
  76. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts +1 -2
  77. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  78. package/dist/feature-libraries/chunked-forest/uniformChunk.js +13 -13
  79. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  80. package/dist/feature-libraries/default-schema/defaultSchema.d.ts.map +1 -1
  81. package/dist/feature-libraries/default-schema/defaultSchema.js +1 -0
  82. package/dist/feature-libraries/default-schema/defaultSchema.js.map +1 -1
  83. package/dist/feature-libraries/default-schema/schemaChecker.d.ts.map +1 -1
  84. package/dist/feature-libraries/default-schema/schemaChecker.js +2 -1
  85. package/dist/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  86. package/dist/feature-libraries/index.d.ts +1 -1
  87. package/dist/feature-libraries/index.d.ts.map +1 -1
  88. package/dist/feature-libraries/index.js +6 -2
  89. package/dist/feature-libraries/index.js.map +1 -1
  90. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts +8 -1
  91. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  92. package/dist/feature-libraries/indexing/anchorTreeIndex.js +31 -5
  93. package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  94. package/dist/feature-libraries/modular-schema/discrepancies.d.ts +84 -24
  95. package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
  96. package/dist/feature-libraries/modular-schema/discrepancies.js +32 -33
  97. package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  98. package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
  99. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  100. package/dist/feature-libraries/modular-schema/index.js +5 -1
  101. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  102. package/dist/feature-libraries/modular-schema/isNeverTree.d.ts +0 -1
  103. package/dist/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
  104. package/dist/feature-libraries/modular-schema/isNeverTree.js +0 -1
  105. package/dist/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
  106. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts +6 -6
  107. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts.map +1 -1
  108. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts +7 -7
  109. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts.map +1 -1
  110. package/dist/feature-libraries/schema-edits/schemaChangeFormat.d.ts +12 -12
  111. package/dist/feature-libraries/sequence-field/formatV1.d.ts +99 -99
  112. package/dist/feature-libraries/sequence-field/formatV1.d.ts.map +1 -1
  113. package/dist/feature-libraries/sequence-field/formatV2.d.ts +76 -76
  114. package/dist/feature-libraries/sequence-field/formatV2.d.ts.map +1 -1
  115. package/dist/feature-libraries/sequence-field/formatV3.d.ts +54 -54
  116. package/dist/feature-libraries/sequence-field/types.d.ts +0 -1
  117. package/dist/feature-libraries/sequence-field/types.d.ts.map +1 -1
  118. package/dist/feature-libraries/sequence-field/types.js.map +1 -1
  119. package/dist/index.d.ts +4 -5
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +1 -14
  122. package/dist/index.js.map +1 -1
  123. package/dist/packageVersion.d.ts +1 -1
  124. package/dist/packageVersion.js +1 -1
  125. package/dist/packageVersion.js.map +1 -1
  126. package/dist/shared-tree/index.d.ts +1 -1
  127. package/dist/shared-tree/index.d.ts.map +1 -1
  128. package/dist/shared-tree/index.js.map +1 -1
  129. package/dist/shared-tree/schematizeTree.d.ts +1 -1
  130. package/dist/shared-tree/schematizeTree.d.ts.map +1 -1
  131. package/dist/shared-tree/schematizeTree.js +6 -6
  132. package/dist/shared-tree/schematizeTree.js.map +1 -1
  133. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  134. package/dist/shared-tree/schematizingTreeView.js +8 -12
  135. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  136. package/dist/shared-tree/sharedTree.d.ts +25 -7
  137. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  138. package/dist/shared-tree/sharedTree.js +104 -15
  139. package/dist/shared-tree/sharedTree.js.map +1 -1
  140. package/dist/shared-tree/treeCheckout.d.ts +35 -12
  141. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  142. package/dist/shared-tree/treeCheckout.js +159 -127
  143. package/dist/shared-tree/treeCheckout.js.map +1 -1
  144. package/dist/shared-tree-core/branch.d.ts +13 -35
  145. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  146. package/dist/shared-tree-core/branch.js +12 -77
  147. package/dist/shared-tree-core/branch.js.map +1 -1
  148. package/dist/shared-tree-core/branchCommitEnricher.d.ts +7 -1
  149. package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  150. package/dist/shared-tree-core/branchCommitEnricher.js +16 -18
  151. package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
  152. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  153. package/dist/shared-tree-core/editManager.js +2 -2
  154. package/dist/shared-tree-core/editManager.js.map +1 -1
  155. package/dist/shared-tree-core/index.d.ts +3 -3
  156. package/dist/shared-tree-core/index.d.ts.map +1 -1
  157. package/dist/shared-tree-core/index.js +2 -2
  158. package/dist/shared-tree-core/index.js.map +1 -1
  159. package/dist/shared-tree-core/sharedTreeCore.d.ts +2 -9
  160. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  161. package/dist/shared-tree-core/sharedTreeCore.js +4 -16
  162. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  163. package/dist/shared-tree-core/transaction.d.ts +38 -0
  164. package/dist/shared-tree-core/transaction.d.ts.map +1 -1
  165. package/dist/shared-tree-core/transaction.js +118 -6
  166. package/dist/shared-tree-core/transaction.js.map +1 -1
  167. package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
  168. package/dist/simple-tree/api/conciseTree.js +1 -1
  169. package/dist/simple-tree/api/conciseTree.js.map +1 -1
  170. package/dist/simple-tree/api/create.d.ts.map +1 -1
  171. package/dist/simple-tree/api/create.js +5 -1
  172. package/dist/simple-tree/api/create.js.map +1 -1
  173. package/dist/simple-tree/api/customTree.d.ts +14 -2
  174. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  175. package/dist/simple-tree/api/customTree.js +53 -3
  176. package/dist/simple-tree/api/customTree.js.map +1 -1
  177. package/dist/simple-tree/api/index.d.ts +2 -2
  178. package/dist/simple-tree/api/index.d.ts.map +1 -1
  179. package/dist/simple-tree/api/index.js +4 -1
  180. package/dist/simple-tree/api/index.js.map +1 -1
  181. package/dist/simple-tree/api/schemaFactory.d.ts +48 -0
  182. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  183. package/dist/simple-tree/api/schemaFactory.js +5 -2
  184. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  185. package/dist/simple-tree/api/simpleSchema.d.ts +3 -1
  186. package/dist/simple-tree/api/simpleSchema.d.ts.map +1 -1
  187. package/dist/simple-tree/api/simpleSchema.js.map +1 -1
  188. package/dist/simple-tree/api/simpleTreeIndex.js +3 -1
  189. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  190. package/dist/simple-tree/api/storedSchema.d.ts +4 -4
  191. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  192. package/dist/simple-tree/api/storedSchema.js +8 -21
  193. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  194. package/dist/simple-tree/api/tree.d.ts +1 -0
  195. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  196. package/dist/simple-tree/api/tree.js.map +1 -1
  197. package/dist/simple-tree/api/verboseTree.js +1 -1
  198. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  199. package/dist/simple-tree/api/view.d.ts +14 -9
  200. package/dist/simple-tree/api/view.d.ts.map +1 -1
  201. package/dist/simple-tree/api/view.js +129 -40
  202. package/dist/simple-tree/api/view.js.map +1 -1
  203. package/dist/simple-tree/index.d.ts +2 -2
  204. package/dist/simple-tree/index.d.ts.map +1 -1
  205. package/dist/simple-tree/index.js +5 -2
  206. package/dist/simple-tree/index.js.map +1 -1
  207. package/dist/simple-tree/leafNodeSchema.d.ts +0 -15
  208. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  209. package/dist/simple-tree/leafNodeSchema.js +0 -15
  210. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  211. package/dist/simple-tree/objectNode.d.ts +8 -3
  212. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  213. package/dist/simple-tree/objectNode.js +18 -2
  214. package/dist/simple-tree/objectNode.js.map +1 -1
  215. package/dist/simple-tree/objectNodeTypes.d.ts +4 -0
  216. package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
  217. package/dist/simple-tree/objectNodeTypes.js.map +1 -1
  218. package/dist/simple-tree/schemaTypes.d.ts +4 -2
  219. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  220. package/dist/simple-tree/schemaTypes.js.map +1 -1
  221. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  222. package/dist/simple-tree/toStoredSchema.js +18 -13
  223. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  224. package/dist/util/brand.d.ts +0 -2
  225. package/dist/util/brand.d.ts.map +1 -1
  226. package/dist/util/brand.js +0 -1
  227. package/dist/util/brand.js.map +1 -1
  228. package/dist/util/index.d.ts +1 -1
  229. package/dist/util/index.d.ts.map +1 -1
  230. package/dist/util/index.js +2 -1
  231. package/dist/util/index.js.map +1 -1
  232. package/dist/util/typeCheck.d.ts +0 -2
  233. package/dist/util/typeCheck.d.ts.map +1 -1
  234. package/dist/util/typeCheck.js.map +1 -1
  235. package/dist/util/utils.d.ts +13 -0
  236. package/dist/util/utils.d.ts.map +1 -1
  237. package/dist/util/utils.js +23 -1
  238. package/dist/util/utils.js.map +1 -1
  239. package/lib/core/index.d.ts +2 -2
  240. package/lib/core/index.d.ts.map +1 -1
  241. package/lib/core/index.js +2 -2
  242. package/lib/core/index.js.map +1 -1
  243. package/lib/core/rebase/utils.d.ts.map +1 -1
  244. package/lib/core/rebase/utils.js +3 -10
  245. package/lib/core/rebase/utils.js.map +1 -1
  246. package/lib/core/schema-stored/format.d.ts +0 -3
  247. package/lib/core/schema-stored/format.d.ts.map +1 -1
  248. package/lib/core/schema-stored/format.js.map +1 -1
  249. package/lib/core/schema-stored/schema.d.ts +12 -10
  250. package/lib/core/schema-stored/schema.d.ts.map +1 -1
  251. package/lib/core/schema-stored/schema.js +3 -5
  252. package/lib/core/schema-stored/schema.js.map +1 -1
  253. package/lib/core/schema-view/index.d.ts +1 -1
  254. package/lib/core/schema-view/index.d.ts.map +1 -1
  255. package/lib/core/schema-view/index.js +1 -1
  256. package/lib/core/schema-view/index.js.map +1 -1
  257. package/lib/core/schema-view/view.d.ts +0 -7
  258. package/lib/core/schema-view/view.d.ts.map +1 -1
  259. package/lib/core/schema-view/view.js +0 -11
  260. package/lib/core/schema-view/view.js.map +1 -1
  261. package/lib/{feature-libraries/chunked-forest → core/tree}/chunk.d.ts +2 -1
  262. package/lib/core/tree/chunk.d.ts.map +1 -0
  263. package/lib/{feature-libraries/chunked-forest → core/tree}/chunk.js +1 -1
  264. package/lib/core/tree/chunk.js.map +1 -0
  265. package/lib/core/tree/index.d.ts +1 -0
  266. package/lib/core/tree/index.d.ts.map +1 -1
  267. package/lib/core/tree/index.js +1 -0
  268. package/lib/core/tree/index.js.map +1 -1
  269. package/lib/core/tree/treeTextFormat.d.ts +0 -5
  270. package/lib/core/tree/treeTextFormat.d.ts.map +1 -1
  271. package/lib/core/tree/treeTextFormat.js.map +1 -1
  272. package/lib/core/tree/types.d.ts +0 -5
  273. package/lib/core/tree/types.d.ts.map +1 -1
  274. package/lib/core/tree/types.js +0 -1
  275. package/lib/core/tree/types.js.map +1 -1
  276. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +1 -2
  277. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  278. package/lib/feature-libraries/chunked-forest/basicChunk.js +1 -1
  279. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  280. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +1 -2
  281. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  282. package/lib/feature-libraries/chunked-forest/chunkTree.js +1 -2
  283. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  284. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -2
  285. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  286. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  287. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.d.ts +1 -2
  288. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.d.ts.map +1 -1
  289. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
  290. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +1 -2
  291. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  292. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  293. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +1 -1
  294. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  295. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  296. package/lib/feature-libraries/chunked-forest/emptyChunk.d.ts +1 -1
  297. package/lib/feature-libraries/chunked-forest/emptyChunk.d.ts.map +1 -1
  298. package/lib/feature-libraries/chunked-forest/emptyChunk.js +1 -2
  299. package/lib/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
  300. package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
  301. package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  302. package/lib/feature-libraries/chunked-forest/index.js +1 -1
  303. package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
  304. package/lib/feature-libraries/chunked-forest/sequenceChunk.d.ts +1 -1
  305. package/lib/feature-libraries/chunked-forest/sequenceChunk.d.ts.map +1 -1
  306. package/lib/feature-libraries/chunked-forest/sequenceChunk.js +1 -1
  307. package/lib/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
  308. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts +1 -2
  309. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  310. package/lib/feature-libraries/chunked-forest/uniformChunk.js +1 -1
  311. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  312. package/lib/feature-libraries/default-schema/defaultSchema.d.ts.map +1 -1
  313. package/lib/feature-libraries/default-schema/defaultSchema.js +1 -0
  314. package/lib/feature-libraries/default-schema/defaultSchema.js.map +1 -1
  315. package/lib/feature-libraries/default-schema/schemaChecker.d.ts.map +1 -1
  316. package/lib/feature-libraries/default-schema/schemaChecker.js +2 -1
  317. package/lib/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  318. package/lib/feature-libraries/index.d.ts +1 -1
  319. package/lib/feature-libraries/index.d.ts.map +1 -1
  320. package/lib/feature-libraries/index.js +1 -1
  321. package/lib/feature-libraries/index.js.map +1 -1
  322. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts +8 -1
  323. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  324. package/lib/feature-libraries/indexing/anchorTreeIndex.js +31 -5
  325. package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  326. package/lib/feature-libraries/modular-schema/discrepancies.d.ts +84 -24
  327. package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
  328. package/lib/feature-libraries/modular-schema/discrepancies.js +25 -28
  329. package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  330. package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
  331. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  332. package/lib/feature-libraries/modular-schema/index.js +1 -1
  333. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  334. package/lib/feature-libraries/modular-schema/isNeverTree.d.ts +0 -1
  335. package/lib/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
  336. package/lib/feature-libraries/modular-schema/isNeverTree.js +0 -1
  337. package/lib/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
  338. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts +6 -6
  339. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts.map +1 -1
  340. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts +7 -7
  341. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts.map +1 -1
  342. package/lib/feature-libraries/schema-edits/schemaChangeFormat.d.ts +12 -12
  343. package/lib/feature-libraries/sequence-field/formatV1.d.ts +99 -99
  344. package/lib/feature-libraries/sequence-field/formatV1.d.ts.map +1 -1
  345. package/lib/feature-libraries/sequence-field/formatV2.d.ts +76 -76
  346. package/lib/feature-libraries/sequence-field/formatV2.d.ts.map +1 -1
  347. package/lib/feature-libraries/sequence-field/formatV3.d.ts +54 -54
  348. package/lib/feature-libraries/sequence-field/types.d.ts +0 -1
  349. package/lib/feature-libraries/sequence-field/types.d.ts.map +1 -1
  350. package/lib/feature-libraries/sequence-field/types.js.map +1 -1
  351. package/lib/index.d.ts +4 -5
  352. package/lib/index.d.ts.map +1 -1
  353. package/lib/index.js +2 -3
  354. package/lib/index.js.map +1 -1
  355. package/lib/packageVersion.d.ts +1 -1
  356. package/lib/packageVersion.js +1 -1
  357. package/lib/packageVersion.js.map +1 -1
  358. package/lib/shared-tree/index.d.ts +1 -1
  359. package/lib/shared-tree/index.d.ts.map +1 -1
  360. package/lib/shared-tree/index.js.map +1 -1
  361. package/lib/shared-tree/schematizeTree.d.ts +1 -1
  362. package/lib/shared-tree/schematizeTree.d.ts.map +1 -1
  363. package/lib/shared-tree/schematizeTree.js +7 -7
  364. package/lib/shared-tree/schematizeTree.js.map +1 -1
  365. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  366. package/lib/shared-tree/schematizingTreeView.js +10 -14
  367. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  368. package/lib/shared-tree/sharedTree.d.ts +25 -7
  369. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  370. package/lib/shared-tree/sharedTree.js +105 -16
  371. package/lib/shared-tree/sharedTree.js.map +1 -1
  372. package/lib/shared-tree/treeCheckout.d.ts +35 -12
  373. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  374. package/lib/shared-tree/treeCheckout.js +161 -129
  375. package/lib/shared-tree/treeCheckout.js.map +1 -1
  376. package/lib/shared-tree-core/branch.d.ts +13 -35
  377. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  378. package/lib/shared-tree-core/branch.js +12 -76
  379. package/lib/shared-tree-core/branch.js.map +1 -1
  380. package/lib/shared-tree-core/branchCommitEnricher.d.ts +7 -1
  381. package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  382. package/lib/shared-tree-core/branchCommitEnricher.js +16 -18
  383. package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
  384. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  385. package/lib/shared-tree-core/editManager.js +3 -3
  386. package/lib/shared-tree-core/editManager.js.map +1 -1
  387. package/lib/shared-tree-core/index.d.ts +3 -3
  388. package/lib/shared-tree-core/index.d.ts.map +1 -1
  389. package/lib/shared-tree-core/index.js +2 -2
  390. package/lib/shared-tree-core/index.js.map +1 -1
  391. package/lib/shared-tree-core/sharedTreeCore.d.ts +2 -9
  392. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  393. package/lib/shared-tree-core/sharedTreeCore.js +4 -16
  394. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  395. package/lib/shared-tree-core/transaction.d.ts +38 -0
  396. package/lib/shared-tree-core/transaction.d.ts.map +1 -1
  397. package/lib/shared-tree-core/transaction.js +112 -1
  398. package/lib/shared-tree-core/transaction.js.map +1 -1
  399. package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
  400. package/lib/simple-tree/api/conciseTree.js +2 -2
  401. package/lib/simple-tree/api/conciseTree.js.map +1 -1
  402. package/lib/simple-tree/api/create.d.ts.map +1 -1
  403. package/lib/simple-tree/api/create.js +5 -1
  404. package/lib/simple-tree/api/create.js.map +1 -1
  405. package/lib/simple-tree/api/customTree.d.ts +14 -2
  406. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  407. package/lib/simple-tree/api/customTree.js +50 -2
  408. package/lib/simple-tree/api/customTree.js.map +1 -1
  409. package/lib/simple-tree/api/index.d.ts +2 -2
  410. package/lib/simple-tree/api/index.d.ts.map +1 -1
  411. package/lib/simple-tree/api/index.js +2 -1
  412. package/lib/simple-tree/api/index.js.map +1 -1
  413. package/lib/simple-tree/api/schemaFactory.d.ts +48 -0
  414. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  415. package/lib/simple-tree/api/schemaFactory.js +4 -1
  416. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  417. package/lib/simple-tree/api/simpleSchema.d.ts +3 -1
  418. package/lib/simple-tree/api/simpleSchema.d.ts.map +1 -1
  419. package/lib/simple-tree/api/simpleSchema.js.map +1 -1
  420. package/lib/simple-tree/api/simpleTreeIndex.js +3 -1
  421. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  422. package/lib/simple-tree/api/storedSchema.d.ts +4 -4
  423. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  424. package/lib/simple-tree/api/storedSchema.js +5 -18
  425. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  426. package/lib/simple-tree/api/tree.d.ts +1 -0
  427. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  428. package/lib/simple-tree/api/tree.js.map +1 -1
  429. package/lib/simple-tree/api/verboseTree.js +2 -2
  430. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  431. package/lib/simple-tree/api/view.d.ts +14 -9
  432. package/lib/simple-tree/api/view.d.ts.map +1 -1
  433. package/lib/simple-tree/api/view.js +131 -42
  434. package/lib/simple-tree/api/view.js.map +1 -1
  435. package/lib/simple-tree/index.d.ts +2 -2
  436. package/lib/simple-tree/index.d.ts.map +1 -1
  437. package/lib/simple-tree/index.js +2 -2
  438. package/lib/simple-tree/index.js.map +1 -1
  439. package/lib/simple-tree/leafNodeSchema.d.ts +0 -15
  440. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  441. package/lib/simple-tree/leafNodeSchema.js +0 -15
  442. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  443. package/lib/simple-tree/objectNode.d.ts +8 -3
  444. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  445. package/lib/simple-tree/objectNode.js +16 -1
  446. package/lib/simple-tree/objectNode.js.map +1 -1
  447. package/lib/simple-tree/objectNodeTypes.d.ts +4 -0
  448. package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
  449. package/lib/simple-tree/objectNodeTypes.js.map +1 -1
  450. package/lib/simple-tree/schemaTypes.d.ts +4 -2
  451. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  452. package/lib/simple-tree/schemaTypes.js.map +1 -1
  453. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  454. package/lib/simple-tree/toStoredSchema.js +19 -14
  455. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  456. package/lib/util/brand.d.ts +0 -2
  457. package/lib/util/brand.d.ts.map +1 -1
  458. package/lib/util/brand.js +0 -1
  459. package/lib/util/brand.js.map +1 -1
  460. package/lib/util/index.d.ts +1 -1
  461. package/lib/util/index.d.ts.map +1 -1
  462. package/lib/util/index.js +1 -1
  463. package/lib/util/index.js.map +1 -1
  464. package/lib/util/typeCheck.d.ts +0 -2
  465. package/lib/util/typeCheck.d.ts.map +1 -1
  466. package/lib/util/typeCheck.js.map +1 -1
  467. package/lib/util/utils.d.ts +13 -0
  468. package/lib/util/utils.d.ts.map +1 -1
  469. package/lib/util/utils.js +21 -0
  470. package/lib/util/utils.js.map +1 -1
  471. package/package.json +22 -22
  472. package/src/core/index.ts +5 -1
  473. package/src/core/rebase/utils.ts +17 -20
  474. package/src/core/schema-stored/format.ts +0 -3
  475. package/src/core/schema-stored/schema.ts +13 -10
  476. package/src/core/schema-view/index.ts +0 -1
  477. package/src/core/schema-view/view.ts +0 -11
  478. package/src/{feature-libraries/chunked-forest → core/tree}/chunk.ts +4 -4
  479. package/src/core/tree/index.ts +8 -0
  480. package/src/core/tree/treeTextFormat.ts +0 -5
  481. package/src/core/tree/types.ts +0 -5
  482. package/src/feature-libraries/chunked-forest/basicChunk.ts +4 -2
  483. package/src/feature-libraries/chunked-forest/chunkTree.ts +2 -1
  484. package/src/feature-libraries/chunked-forest/chunkedForest.ts +2 -1
  485. package/src/feature-libraries/chunked-forest/codec/chunkCodecUtilities.ts +1 -2
  486. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +6 -2
  487. package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +1 -1
  488. package/src/feature-libraries/chunked-forest/emptyChunk.ts +4 -2
  489. package/src/feature-libraries/chunked-forest/index.ts +1 -1
  490. package/src/feature-libraries/chunked-forest/sequenceChunk.ts +1 -1
  491. package/src/feature-libraries/chunked-forest/uniformChunk.ts +4 -1
  492. package/src/feature-libraries/default-schema/defaultSchema.ts +1 -0
  493. package/src/feature-libraries/default-schema/schemaChecker.ts +4 -1
  494. package/src/feature-libraries/index.ts +13 -0
  495. package/src/feature-libraries/indexing/anchorTreeIndex.ts +34 -5
  496. package/src/feature-libraries/modular-schema/discrepancies.ts +76 -38
  497. package/src/feature-libraries/modular-schema/index.ts +13 -0
  498. package/src/feature-libraries/modular-schema/isNeverTree.ts +0 -2
  499. package/src/feature-libraries/sequence-field/types.ts +0 -1
  500. package/src/index.ts +1 -29
  501. package/src/packageVersion.ts +1 -1
  502. package/src/shared-tree/index.ts +1 -0
  503. package/src/shared-tree/schematizeTree.ts +6 -10
  504. package/src/shared-tree/schematizingTreeView.ts +11 -21
  505. package/src/shared-tree/sharedTree.ts +173 -41
  506. package/src/shared-tree/treeCheckout.ts +224 -175
  507. package/src/shared-tree-core/branch.ts +29 -122
  508. package/src/shared-tree-core/branchCommitEnricher.ts +19 -20
  509. package/src/shared-tree-core/editManager.ts +3 -8
  510. package/src/shared-tree-core/index.ts +2 -1
  511. package/src/shared-tree-core/sharedTreeCore.ts +8 -19
  512. package/src/shared-tree-core/transaction.ts +145 -0
  513. package/src/simple-tree/api/conciseTree.ts +2 -2
  514. package/src/simple-tree/api/create.ts +5 -1
  515. package/src/simple-tree/api/customTree.ts +69 -1
  516. package/src/simple-tree/api/index.ts +12 -2
  517. package/src/simple-tree/api/schemaFactory.ts +62 -1
  518. package/src/simple-tree/api/simpleSchema.ts +3 -1
  519. package/src/simple-tree/api/simpleTreeIndex.ts +2 -0
  520. package/src/simple-tree/api/storedSchema.ts +7 -22
  521. package/src/simple-tree/api/tree.ts +6 -0
  522. package/src/simple-tree/api/verboseTree.ts +2 -2
  523. package/src/simple-tree/api/view.ts +197 -51
  524. package/src/simple-tree/index.ts +6 -0
  525. package/src/simple-tree/leafNodeSchema.ts +0 -19
  526. package/src/simple-tree/objectNode.ts +26 -2
  527. package/src/simple-tree/objectNodeTypes.ts +5 -0
  528. package/src/simple-tree/schemaTypes.ts +7 -2
  529. package/src/simple-tree/toStoredSchema.ts +25 -19
  530. package/src/util/brand.ts +0 -2
  531. package/src/util/index.ts +1 -0
  532. package/src/util/typeCheck.ts +0 -2
  533. package/src/util/utils.ts +26 -0
  534. package/dist/feature-libraries/chunked-forest/chunk.d.ts.map +0 -1
  535. package/dist/feature-libraries/chunked-forest/chunk.js.map +0 -1
  536. package/lib/feature-libraries/chunked-forest/chunk.d.ts.map +0 -1
  537. package/lib/feature-libraries/chunked-forest/chunk.js.map +0 -1
@@ -4,11 +4,7 @@
4
4
  */
5
5
 
6
6
  import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
7
- import type {
8
- HasListeners,
9
- IEmitter,
10
- Listenable,
11
- } from "@fluidframework/core-interfaces/internal";
7
+ import type { Listenable } from "@fluidframework/core-interfaces/internal";
12
8
  import { createEmitter } from "@fluid-internal/client-utils";
13
9
  import type { IIdCompressor } from "@fluidframework/id-compressor";
14
10
  import {
@@ -44,6 +40,7 @@ import {
44
40
  visitDelta,
45
41
  type RevertibleAlphaFactory,
46
42
  type RevertibleAlpha,
43
+ type GraphCommit,
47
44
  } from "../core/index.js";
48
45
  import {
49
46
  type FieldBatchCodec,
@@ -55,15 +52,14 @@ import {
55
52
  makeFieldBatchCodec,
56
53
  } from "../feature-libraries/index.js";
57
54
  import {
55
+ SquashingTransactionStack,
58
56
  SharedTreeBranch,
59
57
  TransactionResult,
60
- TransactionStack,
61
- getChangeReplaceType,
62
58
  onForkTransitive,
63
59
  type SharedTreeBranchChange,
64
60
  type Transactor,
65
61
  } from "../shared-tree-core/index.js";
66
- import { Breakable, disposeSymbol, fail, getLast, hasSome } from "../util/index.js";
62
+ import { Breakable, disposeSymbol, fail, getOrCreate } from "../util/index.js";
67
63
 
68
64
  import { SharedTreeChangeFamily, hasSchemaChange } from "./sharedTreeChangeFamily.js";
69
65
  import type { SharedTreeChange } from "./sharedTreeChangeTypes.js";
@@ -84,10 +80,21 @@ import { getCheckout, SchematizingSimpleTreeView } from "./schematizingTreeView.
84
80
  * Events for {@link ITreeCheckout}.
85
81
  */
86
82
  export interface CheckoutEvents {
83
+ /**
84
+ * The view is currently in a consistent state, but a batch of changes is about to be processed.
85
+ * @remarks Once this event fires, it is not safe to access the FlexTree, Forest and AnchorSet again until the corresponding {@link CheckoutEvents.afterBatch} fires.
86
+ * Every call to `beforeBatch` will be followed by a corresponding call to `afterBatch` (before any more calls to `beforeBatch`).
87
+ * @param change - The {@link SharedTreeBranchChange | change} to the checkout's active branch that is about to be processed.
88
+ * May be empty if the changes were produced by e.g. a rebase or the initial loading of the document.
89
+ */
90
+ beforeBatch(change: SharedTreeBranchChange<SharedTreeChange>): void;
91
+
87
92
  /**
88
93
  * A batch of changes has finished processing and the view is in a consistent state.
89
- * It is once again safe to access the FlexTree, Forest and AnchorSet.
94
+ * @remarks It is once again safe to access the FlexTree, Forest and AnchorSet.
90
95
  *
96
+ * While every call to `beforeBatch` will be followed by a corresponding call to `afterBatch`, the converse is not true.
97
+ * This event may be fired without a preceding `beforeBatch` event if the checkout's branch and forest were directly updated via e.g. a summary load rather than via normal application of changes.
91
98
  * @remarks
92
99
  * This is mainly useful for knowing when to do followup work scheduled during events from Anchors.
93
100
  */
@@ -260,9 +267,6 @@ export function createTreeCheckout(
260
267
  schema?: TreeStoredSchemaRepository;
261
268
  forest?: IEditableForest;
262
269
  fieldBatchCodec?: FieldBatchCodec;
263
- events?: Listenable<CheckoutEvents> &
264
- IEmitter<CheckoutEvents> &
265
- HasListeners<CheckoutEvents>;
266
270
  removedRoots?: DetachedFieldIndex;
267
271
  chunkCompressionStrategy?: TreeCompressionStrategy;
268
272
  logger?: ITelemetryLoggerExt;
@@ -293,7 +297,6 @@ export function createTreeCheckout(
293
297
  changeFamily,
294
298
  () => idCompressor.generateCompressedId(),
295
299
  );
296
- const events = args?.events ?? createEmitter();
297
300
 
298
301
  return new TreeCheckout(
299
302
  branch,
@@ -301,7 +304,6 @@ export function createTreeCheckout(
301
304
  changeFamily,
302
305
  schema,
303
306
  forest,
304
- events,
305
307
  mintRevisionTag,
306
308
  revisionTagCodec,
307
309
  idCompressor,
@@ -363,16 +365,16 @@ export class TreeCheckout implements ITreeCheckoutFork {
363
365
  */
364
366
  public static readonly revertTelemetryEventName = "RevertRevertible";
365
367
 
368
+ readonly #events = createEmitter<CheckoutEvents>();
369
+ public events: Listenable<CheckoutEvents> = this.#events;
370
+
366
371
  public constructor(
367
- private readonly _branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>,
372
+ branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>,
368
373
  /** True if and only if this checkout is for a forked branch and not the "main branch" of the tree. */
369
374
  public readonly isBranch: boolean,
370
375
  private readonly changeFamily: ChangeFamily<SharedTreeEditBuilder, SharedTreeChange>,
371
376
  public readonly storedSchema: TreeStoredSchemaRepository,
372
377
  public readonly forest: IEditableForest,
373
- public readonly events: Listenable<CheckoutEvents> &
374
- IEmitter<CheckoutEvents> &
375
- HasListeners<CheckoutEvents>,
376
378
  private readonly mintRevisionTag: () => RevisionTag,
377
379
  private readonly revisionTagCodec: RevisionTagCodec,
378
380
  private readonly idCompressor: IIdCompressor,
@@ -385,121 +387,162 @@ export class TreeCheckout implements ITreeCheckoutFork {
385
387
  private readonly logger?: ITelemetryLoggerExt,
386
388
  private readonly breaker: Breakable = new Breakable("TreeCheckout"),
387
389
  ) {
388
- // We subscribe to `beforeChange` rather than `afterChange` here because it's possible that the change is invalid WRT our forest.
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.
390
- // In such a case we will crash here, preventing the change from being added to the commit graph, and preventing `afterChange` from firing.
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`.
392
- _branch.events.on("beforeChange", (event) => {
393
- if (event.change !== undefined) {
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;
390
+ this.#transaction = new SquashingTransactionStack(
391
+ branch,
392
+ (commits) => {
393
+ const revision = this.mintRevisionTag();
394
+ for (const transactionStep of commits) {
395
+ this.removedRoots.updateMajor(transactionStep.revision, revision);
403
396
  }
404
397
 
405
- // Conflicts due to schema will be empty and thus are not applied.
406
- for (const change of event.change.change.changes) {
407
- if (change.type === "data") {
408
- const delta = intoDelta(tagChange(change.innerChange, revision));
409
- this.withCombinedVisitor((visitor) => {
410
- visitDelta(delta, visitor, this.removedRoots, revision);
411
- });
412
- } else if (change.type === "schema") {
413
- // Schema changes from a current to a new schema are expected to be backwards compatible.
414
- // This guarantees that all data in the forest (which is valid before the schema change)
415
- // is also valid under the new schema.
416
- // Note however, that such schema changes may in some cases be rolled back:
417
- // Case 1: A transaction with a schema change may be aborted.
418
- // The transaction may have made some data changes that would render some trees invalid
419
- // under the old schema, but these changes will also be rolled back, thereby putting the forest
420
- // back in the state before the transaction, which is valid under the original (reinstated) schema.
421
- // Case 2: A branch with a schema change may be rebased such that the schema change (because
422
- // of a constraint) is no longer applied.
423
- // Such a branch may contain data changes that would render some trees invalid under the
424
- // original schema. These data changes may not necessarily be rolled back.
425
- // They will however be rebased over the rollback of the schema change. This rebasing will
426
- // ensure that these data changes are muted if they would render some trees invalid under the
427
- // original (reinstated) schema.
428
- storedSchema.apply(change.innerChange.schema.new);
429
- } else {
430
- fail("Unknown Shared Tree change type.");
398
+ const squashedChange = this.changeFamily.rebaser.compose(commits);
399
+ const change = this.changeFamily.rebaser.changeRevision(squashedChange, revision);
400
+ return tagChange(change, revision);
401
+ },
402
+ () => {
403
+ // Keep track of all the forks created during the transaction so that we can dispose them when the transaction ends.
404
+ // This is a policy decision that we think is useful for the user, but it is not necessary for correctness.
405
+ const forks = new Set<TreeCheckout>();
406
+ const onDisposeUnSubscribes: (() => void)[] = [];
407
+ const onForkUnSubscribe = onForkTransitive(this, (fork) => {
408
+ forks.add(fork);
409
+ onDisposeUnSubscribes.push(fork.events.on("dispose", () => forks.delete(fork)));
410
+ });
411
+ // When each transaction is started, take a snapshot of the current state of removed roots
412
+ const removedRootsSnapshot = this.removedRoots.clone();
413
+ return (result) => {
414
+ switch (result) {
415
+ case TransactionResult.Abort:
416
+ this.removedRoots = removedRootsSnapshot;
417
+ break;
418
+ case TransactionResult.Commit:
419
+ if (!this.transaction.isInProgress()) {
420
+ // The changes in a transaction squash commit have already applied to the checkout and are known to be valid, so we can validate the squash commit automatically.
421
+ this.validateCommit(this.#transaction.branch.getHead());
422
+ }
423
+ break;
424
+ default:
425
+ unreachableCase(result);
431
426
  }
432
- }
433
- this.events.emit("afterBatch");
434
- }
435
- });
436
- _branch.events.on("afterChange", (event) => {
427
+
428
+ forks.forEach((fork) => fork.dispose());
429
+ onDisposeUnSubscribes.forEach((unsubscribe) => unsubscribe());
430
+ onForkUnSubscribe();
431
+ };
432
+ },
433
+ );
434
+
435
+ branch.events.on("afterChange", (event) => {
437
436
  // The following logic allows revertibles to be generated for the change.
438
- // Currently only appends (including merges) and transaction commits are supported.
439
- if (!this.transaction.isInProgress()) {
440
- if (
441
- event.type === "append" ||
442
- (event.type === "replace" && getChangeReplaceType(event) === "transactionCommit")
443
- ) {
444
- // TODO:#20949: When the SharedTree is detached, these commits will already have been garbage collected.
445
- // Figure out a way to generate revertibles before the commits are garbage collected.
446
- for (const commit of event.newCommits) {
447
- const kind = event.type === "append" ? event.kind : CommitKind.Default;
448
- const { change, revision } = commit;
449
-
450
- const getRevertible = hasSchemaChange(change)
451
- ? undefined
452
- : (onRevertibleDisposed?: (revertible: RevertibleAlpha) => void) => {
453
- if (!withinEventContext) {
454
- throw new UsageError(
455
- "Cannot get a revertible outside of the context of a changed event.",
456
- );
457
- }
458
- if (this.revertibleCommitBranches.get(revision) !== undefined) {
459
- throw new UsageError(
460
- "Cannot generate the same revertible more than once. Note that this can happen when multiple changed event listeners are registered.",
461
- );
462
- }
463
- const revertible = this.createRevertible(
464
- revision,
465
- kind,
466
- this,
467
- onRevertibleDisposed,
437
+ // Currently only appends (including merges and transaction commits) are supported.
438
+ if (event.type === "append") {
439
+ // TODO:#20949: When the SharedTree is detached, these commits will already have been garbage collected.
440
+ // Figure out a way to generate revertibles before the commits are garbage collected.
441
+ for (const commit of event.newCommits) {
442
+ const kind = event.type === "append" ? event.kind : CommitKind.Default;
443
+ const { change, revision } = commit;
444
+
445
+ const getRevertible = hasSchemaChange(change)
446
+ ? undefined
447
+ : (onRevertibleDisposed?: (revertible: RevertibleAlpha) => void) => {
448
+ if (!withinEventContext) {
449
+ throw new UsageError(
450
+ "Cannot get a revertible outside of the context of a changed event.",
468
451
  );
469
- this.revertibleCommitBranches.set(revision, _branch.fork(commit));
470
- this.revertibles.add(revertible);
471
- return revertible;
472
- };
473
-
474
- let withinEventContext = true;
475
- this.events.emit("changed", { isLocal: true, kind }, getRevertible);
476
- withinEventContext = false;
477
- }
478
- } else if (this.isRemoteChangeEvent(event)) {
479
- // TODO: figure out how to plumb through commit kind info for remote changes
480
- this.events.emit("changed", { isLocal: false, kind: CommitKind.Default });
452
+ }
453
+ if (this.revertibleCommitBranches.get(revision) !== undefined) {
454
+ throw new UsageError(
455
+ "Cannot generate the same revertible more than once. Note that this can happen when multiple changed event listeners are registered.",
456
+ );
457
+ }
458
+ const revertible = this.createRevertible(
459
+ revision,
460
+ kind,
461
+ this,
462
+ onRevertibleDisposed,
463
+ );
464
+ this.revertibleCommitBranches.set(
465
+ revision,
466
+ this.#transaction.activeBranch.fork(commit),
467
+ );
468
+ this.revertibles.add(revertible);
469
+ return revertible;
470
+ };
471
+
472
+ let withinEventContext = true;
473
+ this.#events.emit("changed", { isLocal: true, kind }, getRevertible);
474
+ withinEventContext = false;
481
475
  }
476
+ } else if (this.isRemoteChangeEvent(event)) {
477
+ // TODO: figure out how to plumb through commit kind info for remote changes
478
+ this.#events.emit("changed", { isLocal: false, kind: CommitKind.Default });
482
479
  }
483
480
  });
484
481
 
482
+ this.#transaction.activeBranchEvents.on("afterChange", this.onAfterChange);
483
+ this.#transaction.activeBranchEvents.on("ancestryTrimmed", this.onAncestryTrimmed);
484
+ }
485
+
486
+ private readonly onAfterChange = (event: SharedTreeBranchChange<SharedTreeChange>): void => {
487
+ this.#events.emit("beforeBatch", event);
488
+ if (event.change !== undefined) {
489
+ const revision =
490
+ event.type === "rebase"
491
+ ? this.#transaction.activeBranch.getHead().revision
492
+ : event.change.revision;
493
+
494
+ // Conflicts due to schema will be empty and thus are not applied.
495
+ for (const change of event.change.change.changes) {
496
+ if (change.type === "data") {
497
+ const delta = intoDelta(tagChange(change.innerChange, revision));
498
+ this.withCombinedVisitor((visitor) => {
499
+ visitDelta(delta, visitor, this.removedRoots, revision);
500
+ });
501
+ } else if (change.type === "schema") {
502
+ // Schema changes from a current to a new schema are expected to be backwards compatible.
503
+ // This guarantees that all data in the forest (which is valid before the schema change)
504
+ // is also valid under the new schema.
505
+ // Note however, that such schema changes may in some cases be rolled back:
506
+ // Case 1: A transaction with a schema change may be aborted.
507
+ // The transaction may have made some data changes that would render some trees invalid
508
+ // under the old schema, but these changes will also be rolled back, thereby putting the forest
509
+ // back in the state before the transaction, which is valid under the original (reinstated) schema.
510
+ // Case 2: A branch with a schema change may be rebased such that the schema change (because
511
+ // of a constraint) is no longer applied.
512
+ // Such a branch may contain data changes that would render some trees invalid under the
513
+ // original schema. These data changes may not necessarily be rolled back.
514
+ // They will however be rebased over the rollback of the schema change. This rebasing will
515
+ // ensure that these data changes are muted if they would render some trees invalid under the
516
+ // original (reinstated) schema.
517
+ this.storedSchema.apply(change.innerChange.schema.new);
518
+ } else {
519
+ fail("Unknown Shared Tree change type.");
520
+ }
521
+ }
522
+ }
523
+ this.#events.emit("afterBatch");
524
+ if (event.type === "append") {
525
+ event.newCommits.forEach((commit) => this.validateCommit(commit));
526
+ }
527
+ };
528
+
529
+ private readonly onAncestryTrimmed = (revisions: RevisionTag[]): void => {
485
530
  // When the branch is trimmed, we can garbage collect any repair data whose latest relevant revision is one of the
486
531
  // trimmed revisions.
487
- _branch.events.on("ancestryTrimmed", (revisions) => {
488
- this.withCombinedVisitor((visitor) => {
489
- revisions.forEach((revision) => {
490
- // get all the roots last created or used by the revision
491
- const roots = this.removedRoots.getRootsLastTouchedByRevision(revision);
492
-
493
- // get the detached field for the root and delete it from the removed roots
494
- for (const root of roots) {
495
- visitor.destroy(this.removedRoots.toFieldKey(root), 1);
496
- }
532
+ this.withCombinedVisitor((visitor) => {
533
+ revisions.forEach((revision) => {
534
+ // get all the roots last created or used by the revision
535
+ const roots = this.removedRoots.getRootsLastTouchedByRevision(revision);
536
+
537
+ // get the detached field for the root and delete it from the removed roots
538
+ for (const root of roots) {
539
+ visitor.destroy(this.removedRoots.toFieldKey(root), 1);
540
+ }
497
541
 
498
- this.removedRoots.deleteRootsLastTouchedByRevision(revision);
499
- });
542
+ this.removedRoots.deleteRootsLastTouchedByRevision(revision);
500
543
  });
501
544
  });
502
- }
545
+ };
503
546
 
504
547
  private withCombinedVisitor(fn: (visitor: DeltaVisitor) => void): void {
505
548
  const anchorVisitor = this.forest.anchors.acquireVisitor();
@@ -622,7 +665,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
622
665
 
623
666
  public get editor(): ISharedTreeEditor {
624
667
  this.checkNotDisposed();
625
- return this._branch.editor;
668
+ return this.#transaction.activeBranchEditor;
626
669
  }
627
670
 
628
671
  public locate(anchor: Anchor): AnchorNode | undefined {
@@ -643,53 +686,14 @@ export class TreeCheckout implements ITreeCheckoutFork {
643
686
  * To avoid updating observers of the view state with intermediate results during a transaction,
644
687
  * use {@link ITreeCheckout#branch} and {@link ISharedTreeFork#merge}.
645
688
  */
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
- });
689
+ readonly #transaction: SquashingTransactionStack<SharedTreeEditBuilder, SharedTreeChange>;
686
690
 
687
691
  public branch(): TreeCheckout {
688
692
  this.checkNotDisposed(
689
693
  "The parent branch has already been disposed and can no longer create new branches.",
690
694
  );
691
695
  const anchors = new AnchorSet();
692
- const branch = this._branch.fork();
696
+ const branch = this.#transaction.activeBranch.fork();
693
697
  const storedSchema = this.storedSchema.clone();
694
698
  const forest = this.forest.clone(storedSchema, anchors);
695
699
  const checkout = new TreeCheckout(
@@ -698,7 +702,6 @@ export class TreeCheckout implements ITreeCheckoutFork {
698
702
  this.changeFamily,
699
703
  storedSchema,
700
704
  forest,
701
- createEmitter(),
702
705
  this.mintRevisionTag,
703
706
  this.revisionTagCodec,
704
707
  this.idCompressor,
@@ -706,7 +709,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
706
709
  this.logger,
707
710
  this.breaker,
708
711
  );
709
- this.events.emit("fork", checkout);
712
+ this.#events.emit("fork", checkout);
710
713
  return checkout;
711
714
  }
712
715
 
@@ -726,7 +729,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
726
729
  0xa5d /* The main branch cannot be rebased onto another branch. */,
727
730
  );
728
731
 
729
- checkout._branch.rebaseOnto(this._branch);
732
+ checkout.#transaction.activeBranch.rebaseOnto(this.#transaction.activeBranch);
730
733
  }
731
734
 
732
735
  public rebaseOnto(checkout: ITreeCheckout): void {
@@ -752,7 +755,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
752
755
  while (checkout.transaction.isInProgress()) {
753
756
  checkout.transaction.commit();
754
757
  }
755
- this._branch.merge(checkout._branch);
758
+ this.#transaction.activeBranch.merge(checkout.#transaction.activeBranch);
756
759
  if (disposeMerged && checkout.isBranch) {
757
760
  // Dispose the merged checkout unless it is the main branch.
758
761
  checkout[disposeSymbol]();
@@ -773,13 +776,13 @@ export class TreeCheckout implements ITreeCheckoutFork {
773
776
  "The branch has already been disposed and cannot be disposed again.",
774
777
  );
775
778
  this.disposed = true;
779
+ this.#transaction.branch.dispose();
776
780
  this.#transaction.dispose();
777
781
  this.purgeRevertibles();
778
- this._branch.dispose();
779
782
  for (const view of this.views) {
780
783
  view.dispose();
781
784
  }
782
- this.events.emit("dispose");
785
+ this.#events.emit("dispose");
783
786
  }
784
787
 
785
788
  public getRemovedRoots(): [string | number | undefined, number, JsonableTree][] {
@@ -800,11 +803,16 @@ export class TreeCheckout implements ITreeCheckoutFork {
800
803
  }
801
804
 
802
805
  /**
803
- * This sets the tip revision as the latest relevant revision for any removed roots that are loaded from a summary.
804
- * This needs to be called right after loading {@link this.removedRoots} from a summary to allow loaded data to be garbage collected.
806
+ * This must be called on the root/main checkout after loading from a summary.
807
+ * @remarks This pattern is necessary because the EditManager skips the normal process of applying commits to branches when loading a summary.
808
+ * Instead, it simply {@link SharedTreeBranch#setHead | mutates} the branches directly which does not propagate the typical events throughout the rest of the system.
805
809
  */
806
- public setTipRevisionForLoadedData(revision: RevisionTag): void {
807
- this.removedRoots.setRevisionsForLoadedData(revision);
810
+ public load(): void {
811
+ // Set the tip revision as the latest relevant revision for any removed roots that are loaded from a summary - this allows them to be garbage collected later.
812
+ // When a load happens, the head of the trunk and the head of the local/main branch must be the same (this is enforced by SharedTree).
813
+ this.removedRoots.setRevisionsForLoadedData(this.#transaction.branch.getHead().revision);
814
+ // The content of the checkout (e.g. the forest) has (maybe) changed, so fire an afterBatch event.
815
+ this.#events.emit("afterBatch");
808
816
  }
809
817
 
810
818
  private purgeRevertibles(): void {
@@ -834,7 +842,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
834
842
  revisionForInvert,
835
843
  );
836
844
 
837
- const headCommit = this._branch.getHead();
845
+ const headCommit = this.#transaction.activeBranch.getHead();
838
846
  // Rebase the inverted change onto any commits that occurred after the undoable commits.
839
847
  if (commitToRevert !== headCommit) {
840
848
  change = tagChange(
@@ -849,7 +857,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
849
857
  );
850
858
  }
851
859
 
852
- this._branch.apply(
860
+ this.#transaction.activeBranch.apply(
853
861
  change,
854
862
  kind === CommitKind.Default || kind === CommitKind.Redo
855
863
  ? CommitKind.Undo
@@ -901,8 +909,49 @@ export class TreeCheckout implements ITreeCheckoutFork {
901
909
  !this.isBranch &&
902
910
  // Remote changes are applied to the main branch by rebasing it onto the trunk.
903
911
  // 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"
912
+ event.type === "rebase"
906
913
  );
907
914
  }
915
+
916
+ // #region Commit Validation
917
+
918
+ /** Used to maintain the contract of {@link onCommitValid}(). */
919
+ #validatedCommits = new WeakMap<
920
+ GraphCommit<SharedTreeChange>,
921
+ ((commit: GraphCommit<SharedTreeChange>) => void)[] | true
922
+ >();
923
+
924
+ /**
925
+ * Registers a function to be called when the given commit is validated.
926
+ * @remarks A commit is validated by the checkout after it has been applied to the checkout's state (e.g. it has an effect on the forest).
927
+ * If the commit applies successfully (i.e. it does not raise any unexpected errors), the commit is considered valid and the registered function is called.
928
+ * If the commit does not apply successfully (because it causes an unexpected error), the function is not called (and the checkout will left in an error state).
929
+ *
930
+ * If the commit has already been validated when this function is called, the function is called immediately and this function returns `true`.
931
+ * Otherwise, the function is registered to be called later and this function returns `false`.
932
+ */
933
+ public onCommitValid(
934
+ commit: GraphCommit<SharedTreeChange>,
935
+ fn: (commit: GraphCommit<SharedTreeChange>) => void,
936
+ ): boolean {
937
+ const validated = getOrCreate(this.#validatedCommits, commit, () => []);
938
+ if (validated === true) {
939
+ fn(commit);
940
+ return true;
941
+ }
942
+
943
+ validated.push(fn);
944
+ return false;
945
+ }
946
+
947
+ /** Mark the given commit as "validated" according to the contract of {@link onCommitValid}(). */
948
+ private validateCommit(commit: GraphCommit<SharedTreeChange>): void {
949
+ const validated = getOrCreate(this.#validatedCommits, commit, () => []);
950
+ if (validated !== true) {
951
+ validated.forEach((fn) => fn(commit));
952
+ this.#validatedCommits.set(commit, true);
953
+ }
954
+ }
955
+
956
+ // #endregion Commit Validation
908
957
  }