@fluidframework/tree 2.1.0-276985 → 2.1.0-281041

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 (437) hide show
  1. package/.eslintrc.cjs +7 -0
  2. package/.vscode/Tree.code-workspace +7 -1
  3. package/README.md +51 -8
  4. package/api-report/tree.alpha.api.md +1 -0
  5. package/api-report/tree.beta.api.md +1 -0
  6. package/api-report/tree.public.api.md +1 -0
  7. package/beta.d.ts +1 -1
  8. package/dist/beta.d.ts +1 -1
  9. package/dist/core/forest/editableForest.d.ts +6 -3
  10. package/dist/core/forest/editableForest.d.ts.map +1 -1
  11. package/dist/core/forest/editableForest.js +14 -4
  12. package/dist/core/forest/editableForest.js.map +1 -1
  13. package/dist/core/index.d.ts +1 -1
  14. package/dist/core/index.d.ts.map +1 -1
  15. package/dist/core/index.js +3 -1
  16. package/dist/core/index.js.map +1 -1
  17. package/dist/core/rebase/index.d.ts +1 -1
  18. package/dist/core/rebase/index.d.ts.map +1 -1
  19. package/dist/core/rebase/index.js +3 -1
  20. package/dist/core/rebase/index.js.map +1 -1
  21. package/dist/core/rebase/types.d.ts +2 -0
  22. package/dist/core/rebase/types.d.ts.map +1 -1
  23. package/dist/core/rebase/types.js +9 -1
  24. package/dist/core/rebase/types.js.map +1 -1
  25. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  26. package/dist/core/tree/visitDelta.js.map +1 -1
  27. package/dist/events/events.d.ts +4 -1
  28. package/dist/events/events.d.ts.map +1 -1
  29. package/dist/events/events.js.map +1 -1
  30. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +1 -1
  31. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  32. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  33. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -0
  34. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  35. package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts +0 -2
  36. package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
  37. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +0 -20
  38. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  39. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +0 -38
  40. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  41. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  42. package/dist/feature-libraries/flex-tree/index.d.ts +1 -1
  43. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  44. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  45. package/dist/feature-libraries/flex-tree/lazyField.d.ts +0 -4
  46. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  47. package/dist/feature-libraries/flex-tree/lazyField.js +1 -14
  48. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  49. package/dist/feature-libraries/flex-tree/lazyNode.d.ts +0 -1
  50. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  51. package/dist/feature-libraries/flex-tree/lazyNode.js +0 -3
  52. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  53. package/dist/feature-libraries/index.d.ts +3 -3
  54. package/dist/feature-libraries/index.d.ts.map +1 -1
  55. package/dist/feature-libraries/index.js +2 -2
  56. package/dist/feature-libraries/index.js.map +1 -1
  57. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +11 -0
  58. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  59. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  60. package/dist/feature-libraries/modular-schema/discrepancies.d.ts +96 -0
  61. package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -0
  62. package/dist/feature-libraries/modular-schema/discrepancies.js +264 -0
  63. package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -0
  64. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +9 -2
  65. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  66. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  67. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  68. package/dist/feature-libraries/modular-schema/genericFieldKind.js +3 -0
  69. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  70. package/dist/feature-libraries/modular-schema/index.d.ts +2 -1
  71. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  72. package/dist/feature-libraries/modular-schema/index.js +3 -1
  73. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  74. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  75. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +42 -26
  76. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  77. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +51 -2
  78. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  79. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +830 -245
  80. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  81. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  82. package/dist/feature-libraries/modular-schema/modularChangeFormat.js +2 -0
  83. package/dist/feature-libraries/modular-schema/modularChangeFormat.js.map +1 -1
  84. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +44 -1
  85. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  86. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  87. package/dist/feature-libraries/node-key/index.d.ts +0 -1
  88. package/dist/feature-libraries/node-key/index.d.ts.map +1 -1
  89. package/dist/feature-libraries/node-key/index.js +1 -3
  90. package/dist/feature-libraries/node-key/index.js.map +1 -1
  91. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  92. package/dist/feature-libraries/optional-field/optionalField.js +1 -0
  93. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  94. package/dist/feature-libraries/sequence-field/index.d.ts +1 -1
  95. package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
  96. package/dist/feature-libraries/sequence-field/index.js +1 -2
  97. package/dist/feature-libraries/sequence-field/index.js.map +1 -1
  98. package/dist/feature-libraries/sequence-field/invert.js +1 -1
  99. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  100. package/dist/feature-libraries/sequence-field/rebase.js +6 -1
  101. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  102. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  103. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +1 -0
  104. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  105. package/dist/feature-libraries/sequence-field/utils.d.ts +2 -17
  106. package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  107. package/dist/feature-libraries/sequence-field/utils.js +31 -39
  108. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  109. package/dist/feature-libraries/typed-schema/typedTreeSchema.d.ts +1 -0
  110. package/dist/feature-libraries/typed-schema/typedTreeSchema.d.ts.map +1 -1
  111. package/dist/feature-libraries/typed-schema/typedTreeSchema.js +2 -0
  112. package/dist/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  113. package/dist/index.d.ts +1 -1
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js.map +1 -1
  116. package/dist/packageVersion.d.ts +1 -1
  117. package/dist/packageVersion.js +1 -1
  118. package/dist/packageVersion.js.map +1 -1
  119. package/dist/public.d.ts +1 -1
  120. package/dist/shared-tree/schematizingTreeView.d.ts +4 -2
  121. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  122. package/dist/shared-tree/schematizingTreeView.js +240 -184
  123. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  124. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  125. package/dist/shared-tree/sharedTree.js +150 -90
  126. package/dist/shared-tree/sharedTree.js.map +1 -1
  127. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  128. package/dist/shared-tree/treeCheckout.js +2 -1
  129. package/dist/shared-tree/treeCheckout.js.map +1 -1
  130. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  131. package/dist/shared-tree-core/branch.js +1 -0
  132. package/dist/shared-tree-core/branch.js.map +1 -1
  133. package/dist/shared-tree-core/sharedTreeCore.d.ts +4 -6
  134. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  135. package/dist/shared-tree-core/sharedTreeCore.js +265 -209
  136. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  137. package/dist/simple-tree/arrayNode.d.ts +4 -0
  138. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  139. package/dist/simple-tree/arrayNode.js +36 -19
  140. package/dist/simple-tree/arrayNode.js.map +1 -1
  141. package/dist/simple-tree/leafNodeSchema.d.ts +22 -1
  142. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  143. package/dist/simple-tree/leafNodeSchema.js +2 -1
  144. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  145. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  146. package/dist/simple-tree/mapNode.js.map +1 -1
  147. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  148. package/dist/simple-tree/objectNode.js +2 -1
  149. package/dist/simple-tree/objectNode.js.map +1 -1
  150. package/dist/simple-tree/proxies.d.ts.map +1 -1
  151. package/dist/simple-tree/proxies.js +2 -4
  152. package/dist/simple-tree/proxies.js.map +1 -1
  153. package/dist/simple-tree/schemaFactory.d.ts +16 -1
  154. package/dist/simple-tree/schemaFactory.d.ts.map +1 -1
  155. package/dist/simple-tree/schemaFactory.js +32 -4
  156. package/dist/simple-tree/schemaFactory.js.map +1 -1
  157. package/dist/simple-tree/schemaTypes.d.ts +36 -1
  158. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  159. package/dist/simple-tree/schemaTypes.js.map +1 -1
  160. package/dist/simple-tree/toFlexSchema.d.ts +2 -2
  161. package/dist/simple-tree/toFlexSchema.d.ts.map +1 -1
  162. package/dist/simple-tree/toFlexSchema.js +3 -2
  163. package/dist/simple-tree/toFlexSchema.js.map +1 -1
  164. package/dist/simple-tree/tree.d.ts +4 -1
  165. package/dist/simple-tree/tree.d.ts.map +1 -1
  166. package/dist/simple-tree/tree.js +48 -1
  167. package/dist/simple-tree/tree.js.map +1 -1
  168. package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
  169. package/dist/simple-tree/treeNodeApi.js +10 -10
  170. package/dist/simple-tree/treeNodeApi.js.map +1 -1
  171. package/dist/simple-tree/types.d.ts +22 -3
  172. package/dist/simple-tree/types.d.ts.map +1 -1
  173. package/dist/simple-tree/types.js +32 -21
  174. package/dist/simple-tree/types.js.map +1 -1
  175. package/dist/util/breakable.d.ts +83 -0
  176. package/dist/util/breakable.d.ts.map +1 -0
  177. package/dist/util/breakable.js +178 -0
  178. package/dist/util/breakable.js.map +1 -0
  179. package/dist/util/index.d.ts +3 -2
  180. package/dist/util/index.d.ts.map +1 -1
  181. package/dist/util/index.js +9 -2
  182. package/dist/util/index.js.map +1 -1
  183. package/dist/util/nestedMap.d.ts +17 -3
  184. package/dist/util/nestedMap.d.ts.map +1 -1
  185. package/dist/util/nestedMap.js +21 -1
  186. package/dist/util/nestedMap.js.map +1 -1
  187. package/dist/util/utils.d.ts +7 -0
  188. package/dist/util/utils.d.ts.map +1 -1
  189. package/dist/util/utils.js +15 -1
  190. package/dist/util/utils.js.map +1 -1
  191. package/internal.d.ts +1 -1
  192. package/lib/beta.d.ts +1 -1
  193. package/lib/core/forest/editableForest.d.ts +6 -3
  194. package/lib/core/forest/editableForest.d.ts.map +1 -1
  195. package/lib/core/forest/editableForest.js +15 -5
  196. package/lib/core/forest/editableForest.js.map +1 -1
  197. package/lib/core/index.d.ts +1 -1
  198. package/lib/core/index.d.ts.map +1 -1
  199. package/lib/core/index.js +1 -1
  200. package/lib/core/index.js.map +1 -1
  201. package/lib/core/rebase/index.d.ts +1 -1
  202. package/lib/core/rebase/index.d.ts.map +1 -1
  203. package/lib/core/rebase/index.js +1 -1
  204. package/lib/core/rebase/index.js.map +1 -1
  205. package/lib/core/rebase/types.d.ts +2 -0
  206. package/lib/core/rebase/types.d.ts.map +1 -1
  207. package/lib/core/rebase/types.js +7 -1
  208. package/lib/core/rebase/types.js.map +1 -1
  209. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  210. package/lib/core/tree/visitDelta.js.map +1 -1
  211. package/lib/events/events.d.ts +4 -1
  212. package/lib/events/events.d.ts.map +1 -1
  213. package/lib/events/events.js.map +1 -1
  214. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +1 -1
  215. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  216. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  217. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -0
  218. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  219. package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts +0 -2
  220. package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
  221. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +0 -20
  222. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  223. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +0 -38
  224. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  225. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  226. package/lib/feature-libraries/flex-tree/index.d.ts +1 -1
  227. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  228. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  229. package/lib/feature-libraries/flex-tree/lazyField.d.ts +0 -4
  230. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  231. package/lib/feature-libraries/flex-tree/lazyField.js +1 -14
  232. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  233. package/lib/feature-libraries/flex-tree/lazyNode.d.ts +0 -1
  234. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  235. package/lib/feature-libraries/flex-tree/lazyNode.js +0 -3
  236. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  237. package/lib/feature-libraries/index.d.ts +3 -3
  238. package/lib/feature-libraries/index.d.ts.map +1 -1
  239. package/lib/feature-libraries/index.js +2 -2
  240. package/lib/feature-libraries/index.js.map +1 -1
  241. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +11 -0
  242. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  243. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  244. package/lib/feature-libraries/modular-schema/discrepancies.d.ts +96 -0
  245. package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -0
  246. package/lib/feature-libraries/modular-schema/discrepancies.js +260 -0
  247. package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -0
  248. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +9 -2
  249. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  250. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  251. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  252. package/lib/feature-libraries/modular-schema/genericFieldKind.js +3 -0
  253. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  254. package/lib/feature-libraries/modular-schema/index.d.ts +2 -1
  255. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  256. package/lib/feature-libraries/modular-schema/index.js +1 -0
  257. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  258. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  259. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +42 -26
  260. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  261. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +51 -2
  262. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  263. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +829 -247
  264. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  265. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  266. package/lib/feature-libraries/modular-schema/modularChangeFormat.js +2 -0
  267. package/lib/feature-libraries/modular-schema/modularChangeFormat.js.map +1 -1
  268. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +44 -1
  269. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  270. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  271. package/lib/feature-libraries/node-key/index.d.ts +0 -1
  272. package/lib/feature-libraries/node-key/index.d.ts.map +1 -1
  273. package/lib/feature-libraries/node-key/index.js +0 -1
  274. package/lib/feature-libraries/node-key/index.js.map +1 -1
  275. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  276. package/lib/feature-libraries/optional-field/optionalField.js +1 -0
  277. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  278. package/lib/feature-libraries/sequence-field/index.d.ts +1 -1
  279. package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
  280. package/lib/feature-libraries/sequence-field/index.js +1 -1
  281. package/lib/feature-libraries/sequence-field/index.js.map +1 -1
  282. package/lib/feature-libraries/sequence-field/invert.js +1 -1
  283. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  284. package/lib/feature-libraries/sequence-field/rebase.js +6 -1
  285. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  286. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  287. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -1
  288. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  289. package/lib/feature-libraries/sequence-field/utils.d.ts +2 -17
  290. package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  291. package/lib/feature-libraries/sequence-field/utils.js +31 -39
  292. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  293. package/lib/feature-libraries/typed-schema/typedTreeSchema.d.ts +1 -0
  294. package/lib/feature-libraries/typed-schema/typedTreeSchema.d.ts.map +1 -1
  295. package/lib/feature-libraries/typed-schema/typedTreeSchema.js +4 -2
  296. package/lib/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  297. package/lib/index.d.ts +1 -1
  298. package/lib/index.d.ts.map +1 -1
  299. package/lib/index.js.map +1 -1
  300. package/lib/packageVersion.d.ts +1 -1
  301. package/lib/packageVersion.js +1 -1
  302. package/lib/packageVersion.js.map +1 -1
  303. package/lib/public.d.ts +1 -1
  304. package/lib/shared-tree/schematizingTreeView.d.ts +4 -2
  305. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  306. package/lib/shared-tree/schematizingTreeView.js +242 -185
  307. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  308. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  309. package/lib/shared-tree/sharedTree.js +151 -90
  310. package/lib/shared-tree/sharedTree.js.map +1 -1
  311. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  312. package/lib/shared-tree/treeCheckout.js +2 -1
  313. package/lib/shared-tree/treeCheckout.js.map +1 -1
  314. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  315. package/lib/shared-tree-core/branch.js +1 -0
  316. package/lib/shared-tree-core/branch.js.map +1 -1
  317. package/lib/shared-tree-core/sharedTreeCore.d.ts +4 -6
  318. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  319. package/lib/shared-tree-core/sharedTreeCore.js +267 -210
  320. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  321. package/lib/simple-tree/arrayNode.d.ts +4 -0
  322. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  323. package/lib/simple-tree/arrayNode.js +38 -21
  324. package/lib/simple-tree/arrayNode.js.map +1 -1
  325. package/lib/simple-tree/leafNodeSchema.d.ts +22 -1
  326. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  327. package/lib/simple-tree/leafNodeSchema.js +1 -1
  328. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  329. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  330. package/lib/simple-tree/mapNode.js.map +1 -1
  331. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  332. package/lib/simple-tree/objectNode.js +3 -2
  333. package/lib/simple-tree/objectNode.js.map +1 -1
  334. package/lib/simple-tree/proxies.d.ts.map +1 -1
  335. package/lib/simple-tree/proxies.js +2 -4
  336. package/lib/simple-tree/proxies.js.map +1 -1
  337. package/lib/simple-tree/schemaFactory.d.ts +16 -1
  338. package/lib/simple-tree/schemaFactory.d.ts.map +1 -1
  339. package/lib/simple-tree/schemaFactory.js +30 -3
  340. package/lib/simple-tree/schemaFactory.js.map +1 -1
  341. package/lib/simple-tree/schemaTypes.d.ts +36 -1
  342. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  343. package/lib/simple-tree/schemaTypes.js.map +1 -1
  344. package/lib/simple-tree/toFlexSchema.d.ts +2 -2
  345. package/lib/simple-tree/toFlexSchema.d.ts.map +1 -1
  346. package/lib/simple-tree/toFlexSchema.js +3 -2
  347. package/lib/simple-tree/toFlexSchema.js.map +1 -1
  348. package/lib/simple-tree/tree.d.ts +4 -1
  349. package/lib/simple-tree/tree.d.ts.map +1 -1
  350. package/lib/simple-tree/tree.js +44 -0
  351. package/lib/simple-tree/tree.js.map +1 -1
  352. package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
  353. package/lib/simple-tree/treeNodeApi.js +11 -11
  354. package/lib/simple-tree/treeNodeApi.js.map +1 -1
  355. package/lib/simple-tree/types.d.ts +22 -3
  356. package/lib/simple-tree/types.d.ts.map +1 -1
  357. package/lib/simple-tree/types.js +32 -21
  358. package/lib/simple-tree/types.js.map +1 -1
  359. package/lib/util/breakable.d.ts +83 -0
  360. package/lib/util/breakable.d.ts.map +1 -0
  361. package/lib/util/breakable.js +171 -0
  362. package/lib/util/breakable.js.map +1 -0
  363. package/lib/util/index.d.ts +3 -2
  364. package/lib/util/index.d.ts.map +1 -1
  365. package/lib/util/index.js +3 -2
  366. package/lib/util/index.js.map +1 -1
  367. package/lib/util/nestedMap.d.ts +17 -3
  368. package/lib/util/nestedMap.d.ts.map +1 -1
  369. package/lib/util/nestedMap.js +19 -0
  370. package/lib/util/nestedMap.js.map +1 -1
  371. package/lib/util/utils.d.ts +7 -0
  372. package/lib/util/utils.d.ts.map +1 -1
  373. package/lib/util/utils.js +13 -0
  374. package/lib/util/utils.js.map +1 -1
  375. package/package.json +29 -27
  376. package/src/core/forest/editableForest.ts +17 -4
  377. package/src/core/index.ts +2 -0
  378. package/src/core/rebase/index.ts +2 -0
  379. package/src/core/rebase/types.ts +17 -0
  380. package/src/core/tree/visitDelta.ts +1 -0
  381. package/src/events/events.ts +4 -2
  382. package/src/feature-libraries/default-schema/defaultEditBuilder.ts +1 -1
  383. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -0
  384. package/src/feature-libraries/flex-map-tree/mapTreeNode.ts +0 -30
  385. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +0 -43
  386. package/src/feature-libraries/flex-tree/index.ts +0 -1
  387. package/src/feature-libraries/flex-tree/lazyField.ts +1 -21
  388. package/src/feature-libraries/flex-tree/lazyNode.ts +0 -6
  389. package/src/feature-libraries/index.ts +1 -2
  390. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +18 -0
  391. package/src/feature-libraries/modular-schema/discrepancies.ts +395 -0
  392. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +10 -2
  393. package/src/feature-libraries/modular-schema/genericFieldKind.ts +3 -0
  394. package/src/feature-libraries/modular-schema/index.ts +2 -0
  395. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +81 -35
  396. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1529 -454
  397. package/src/feature-libraries/modular-schema/modularChangeFormat.ts +2 -0
  398. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +51 -0
  399. package/src/feature-libraries/node-key/index.ts +0 -1
  400. package/src/feature-libraries/optional-field/optionalField.ts +1 -0
  401. package/src/feature-libraries/sequence-field/index.ts +0 -2
  402. package/src/feature-libraries/sequence-field/invert.ts +1 -1
  403. package/src/feature-libraries/sequence-field/rebase.ts +7 -1
  404. package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +2 -1
  405. package/src/feature-libraries/sequence-field/utils.ts +37 -85
  406. package/src/feature-libraries/typed-schema/typedTreeSchema.ts +10 -0
  407. package/src/index.ts +0 -1
  408. package/src/packageVersion.ts +1 -1
  409. package/src/shared-tree/schematizingTreeView.ts +6 -2
  410. package/src/shared-tree/sharedTree.ts +4 -0
  411. package/src/shared-tree/treeCheckout.ts +6 -2
  412. package/src/shared-tree-core/branch.ts +1 -0
  413. package/src/shared-tree-core/sharedTreeCore.ts +18 -6
  414. package/src/simple-tree/arrayNode.ts +49 -22
  415. package/src/simple-tree/leafNodeSchema.ts +1 -1
  416. package/src/simple-tree/mapNode.ts +2 -2
  417. package/src/simple-tree/objectNode.ts +9 -3
  418. package/src/simple-tree/proxies.ts +2 -4
  419. package/src/simple-tree/schemaFactory.ts +37 -2
  420. package/src/simple-tree/schemaTypes.ts +36 -1
  421. package/src/simple-tree/toFlexSchema.ts +5 -4
  422. package/src/simple-tree/tree.ts +65 -4
  423. package/src/simple-tree/treeNodeApi.ts +15 -15
  424. package/src/simple-tree/types.ts +60 -30
  425. package/src/util/breakable.ts +214 -0
  426. package/src/util/index.ts +10 -0
  427. package/src/util/nestedMap.ts +33 -3
  428. package/src/util/utils.ts +17 -0
  429. package/dist/feature-libraries/node-key/nodeKeyIndex.d.ts +0 -41
  430. package/dist/feature-libraries/node-key/nodeKeyIndex.d.ts.map +0 -1
  431. package/dist/feature-libraries/node-key/nodeKeyIndex.js +0 -101
  432. package/dist/feature-libraries/node-key/nodeKeyIndex.js.map +0 -1
  433. package/lib/feature-libraries/node-key/nodeKeyIndex.d.ts +0 -41
  434. package/lib/feature-libraries/node-key/nodeKeyIndex.d.ts.map +0 -1
  435. package/lib/feature-libraries/node-key/nodeKeyIndex.js +0 -97
  436. package/lib/feature-libraries/node-key/nodeKeyIndex.js.map +0 -1
  437. package/src/feature-libraries/node-key/nodeKeyIndex.ts +0 -132
@@ -130,6 +130,8 @@ export const EncodedModularChangeset = Type.Object(
130
130
  maxId: Type.Optional(ChangesetLocalIdSchema),
131
131
  changes: EncodedFieldChangeMap,
132
132
  revisions: Type.ReadonlyOptional(Type.Array(EncodedRevisionInfo)),
133
+ // TODO#8574: separating `builds` and `refreshers` here means that we encode their `EncodedBuilds.trees` separately.
134
+ // This can lead to a less efficient wire representation because of duplicated schema/shape information.
133
135
  builds: Type.Optional(EncodedBuilds),
134
136
  refreshers: Type.Optional(EncodedBuilds),
135
137
  /**
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import type { BTree } from "@tylerbu/sorted-btree-es6";
6
7
  import type {
7
8
  ChangeAtomId,
8
9
  ChangeAtomIdMap,
@@ -10,9 +11,11 @@ import type {
10
11
  FieldKey,
11
12
  FieldKindIdentifier,
12
13
  RevisionInfo,
14
+ RevisionTag,
13
15
  } from "../../core/index.js";
14
16
  import type { Brand } from "../../util/index.js";
15
17
  import type { TreeChunk } from "../chunked-forest/index.js";
18
+ import type { CrossFieldTarget } from "./crossFieldQueries.js";
16
19
 
17
20
  /**
18
21
  * @internal
@@ -30,13 +33,61 @@ export interface ModularChangeset extends HasFieldChanges {
30
33
  */
31
34
  readonly revisions?: readonly RevisionInfo[];
32
35
  readonly fieldChanges: FieldChangeMap;
36
+
37
+ /**
38
+ * Maps from this changeset's canonical ID for a node (see comment on node aliases) to the changes for that node.
39
+ */
33
40
  readonly nodeChanges: ChangeAtomIdMap<NodeChangeset>;
41
+
42
+ /**
43
+ * Maps from this changeset's canonical ID for a node to the ID for the field which contains that node.
44
+ */
45
+ // TODO: Should this be merged with `nodeChanges`?
46
+ readonly nodeToParent: ChangeAtomIdMap<FieldId>;
47
+
48
+ /**
49
+ * Maps from a node ID to another ID for the same node.
50
+ * If a node ID used in this changeset has no entry in this table, then it is the canonical ID for that node.
51
+ * The aliases form a set of trees, where the root of each tree is a canonical ID.
52
+ *
53
+ * When composing changesets with different canonical IDs for the same node,
54
+ * one of those IDs becomes the canonical ID for the composition, while the other is added to this table as an alias.
55
+ *
56
+ * Node aliases are preserved when composing changesets so we can avoid having to find and update all changed node IDs
57
+ * in the field IDs in nodeToParent and crossFieldKeys.
58
+ */
59
+ readonly nodeAliases: ChangeAtomIdMap<NodeId>;
60
+ readonly crossFieldKeys: CrossFieldKeyTable;
34
61
  readonly constraintViolationCount?: number;
35
62
  readonly builds?: ChangeAtomIdMap<TreeChunk>;
36
63
  readonly destroys?: ChangeAtomIdMap<number>;
37
64
  readonly refreshers?: ChangeAtomIdMap<TreeChunk>;
38
65
  }
39
66
 
67
+ export type TupleBTree<K, V> = Brand<BTree<K, V>, "TupleBTree">;
68
+ export type CrossFieldKeyTable = TupleBTree<CrossFieldKeyRange, FieldId>;
69
+ export type CrossFieldKeyRange = readonly [
70
+ CrossFieldTarget,
71
+ RevisionTag | undefined,
72
+ ChangesetLocalId,
73
+ /**
74
+ * The length of this range.
75
+ * TODO: This does not need to be part of the key and could be part of the value instead.
76
+ */
77
+ number,
78
+ ];
79
+
80
+ export type CrossFieldKey = readonly [
81
+ CrossFieldTarget,
82
+ RevisionTag | undefined,
83
+ ChangesetLocalId,
84
+ ];
85
+
86
+ export interface FieldId {
87
+ readonly nodeId: NodeId | undefined;
88
+ readonly field: FieldKey;
89
+ }
90
+
40
91
  /**
41
92
  * @internal
42
93
  */
@@ -10,7 +10,6 @@ export {
10
10
  type StableNodeKey,
11
11
  nodeKeyTreeIdentifier,
12
12
  } from "./nodeKey.js";
13
- export { NodeKeyIndex } from "./nodeKeyIndex.js";
14
13
  export {
15
14
  createNodeKeyManager,
16
15
  isStableNodeKey,
@@ -713,6 +713,7 @@ export const optionalChangeHandler: FieldChangeHandler<
713
713
  getNestedChanges,
714
714
 
715
715
  createEmpty: () => ({ moves: [], childChanges: [] }),
716
+ getCrossFieldKeys: (_change) => [],
716
717
  };
717
718
 
718
719
  function getNestedChanges(change: OptionalChangeset): [NodeId, number | undefined][] {
@@ -42,8 +42,6 @@ export { compose } from "./compose.js";
42
42
  export {
43
43
  getInputLength,
44
44
  isDetach,
45
- newCrossFieldTable,
46
- type CrossFieldTable,
47
45
  cloneMark,
48
46
  extractMarkEffect,
49
47
  } from "./utils.js";
@@ -194,7 +194,6 @@ function invertMark(
194
194
  return applyMovedChanges(invertedMark, mark.revision, crossFieldManager);
195
195
  }
196
196
  case "AttachAndDetach": {
197
- // Which should get the child change? Don't want to invert twice
198
197
  const attach: Mark = {
199
198
  count: mark.count,
200
199
  cellId: mark.cellId,
@@ -294,6 +293,7 @@ function applyMovedChanges(
294
293
  }
295
294
 
296
295
  if (entry.value !== undefined) {
296
+ manager.onMoveIn(entry.value);
297
297
  return [withNodeChange<CellMark<MoveOut>, MoveOut>(mark, entry.value)];
298
298
  }
299
299
 
@@ -270,6 +270,7 @@ function rebaseMark(
270
270
  0x8dc /* Unexpected collision of new node changes */,
271
271
  );
272
272
  rebasedMark.changes = movedNodeChanges;
273
+ moveEffects.onMoveIn(movedNodeChanges);
273
274
  }
274
275
 
275
276
  return rebaseMarkIgnoreChild(rebasedMark, baseMark, moveEffects);
@@ -514,7 +515,12 @@ function getMovedEffect(
514
515
  ): MarkEffect | undefined {
515
516
  const effect = getMoveEffect(moveEffects, CrossFieldTarget.Destination, revision, id, count);
516
517
  assert(effect.length === count, 0x6f3 /* Expected effect to cover entire mark */);
517
- return effect.value?.movedEffect;
518
+ const movedEffect = effect.value?.movedEffect;
519
+ if (movedEffect !== undefined && movedEffect.type === "MoveOut") {
520
+ moveEffects.moveKey(CrossFieldTarget.Source, movedEffect.revision, movedEffect.id, count);
521
+ }
522
+
523
+ return movedEffect;
518
524
  }
519
525
 
520
526
  function getMovedChangesFromBaseMark(
@@ -11,7 +11,7 @@ import { sequenceFieldChangeCodecFactory } from "./sequenceFieldCodecs.js";
11
11
  import { type SequenceFieldEditor, sequenceFieldEditor } from "./sequenceFieldEditor.js";
12
12
  import { sequenceFieldToDelta } from "./sequenceFieldToDelta.js";
13
13
  import type { Changeset } from "./types.js";
14
- import { createEmpty, getNestedChanges, isEmpty } from "./utils.js";
14
+ import { createEmpty, getCrossFieldKeys, getNestedChanges, isEmpty } from "./utils.js";
15
15
 
16
16
  export type SequenceFieldChangeHandler = FieldChangeHandler<Changeset, SequenceFieldEditor>;
17
17
 
@@ -24,4 +24,5 @@ export const sequenceFieldChangeHandler: SequenceFieldChangeHandler = {
24
24
  isEmpty,
25
25
  getNestedChanges,
26
26
  createEmpty,
27
+ getCrossFieldKeys,
27
28
  };
@@ -13,20 +13,11 @@ import {
13
13
  areEqualChangeAtomIds,
14
14
  makeChangeAtomId,
15
15
  } from "../../core/index.js";
16
+ import { type Mutable, brand, fail } from "../../util/index.js";
16
17
  import {
17
- type Mutable,
18
- type RangeMap,
19
- brand,
20
- fail,
21
- getFromRangeMap,
22
- } from "../../util/index.js";
23
- import {
24
- type CrossFieldManager,
25
- type CrossFieldQuerySet,
26
18
  CrossFieldTarget,
27
19
  type NodeId,
28
- addCrossFieldQuery,
29
- setInCrossFieldMap,
20
+ type CrossFieldKeyRange,
30
21
  } from "../modular-schema/index.js";
31
22
 
32
23
  import type {
@@ -47,7 +38,6 @@ import {
47
38
  type Insert,
48
39
  type Mark,
49
40
  type MarkEffect,
50
- type MoveId,
51
41
  type MoveIn,
52
42
  type MoveOut,
53
43
  type NoopMark,
@@ -708,79 +698,6 @@ function tryMergeEffects(
708
698
  return undefined;
709
699
  }
710
700
 
711
- /**
712
- * @internal
713
- */
714
- export interface CrossFieldTable<T = unknown> extends CrossFieldManager<T> {
715
- srcQueries: CrossFieldQuerySet;
716
- dstQueries: CrossFieldQuerySet;
717
- isInvalidated: boolean;
718
- mapSrc: Map<RevisionTag | undefined, RangeMap<T>>;
719
- mapDst: Map<RevisionTag | undefined, RangeMap<T>>;
720
- reset: () => void;
721
- }
722
-
723
- /**
724
- * @internal
725
- */
726
- export function newCrossFieldTable<T = unknown>(): CrossFieldTable<T> {
727
- const srcQueries: CrossFieldQuerySet = new Map();
728
- const dstQueries: CrossFieldQuerySet = new Map();
729
- const mapSrc: Map<RevisionTag | undefined, RangeMap<T>> = new Map();
730
- const mapDst: Map<RevisionTag | undefined, RangeMap<T>> = new Map();
731
-
732
- const getMap = (target: CrossFieldTarget): Map<RevisionTag | undefined, RangeMap<T>> =>
733
- target === CrossFieldTarget.Source ? mapSrc : mapDst;
734
-
735
- const getQueries = (target: CrossFieldTarget): CrossFieldQuerySet =>
736
- target === CrossFieldTarget.Source ? srcQueries : dstQueries;
737
-
738
- const table = {
739
- srcQueries,
740
- dstQueries,
741
- isInvalidated: false,
742
- mapSrc,
743
- mapDst,
744
-
745
- get: (
746
- target: CrossFieldTarget,
747
- revision: RevisionTag | undefined,
748
- id: MoveId,
749
- count: number,
750
- addDependency: boolean,
751
- ) => {
752
- if (addDependency) {
753
- addCrossFieldQuery(getQueries(target), revision, id, count);
754
- }
755
- return getFromRangeMap(getMap(target).get(revision) ?? [], id, count);
756
- },
757
- set: (
758
- target: CrossFieldTarget,
759
- revision: RevisionTag | undefined,
760
- id: MoveId,
761
- count: number,
762
- value: T,
763
- invalidateDependents: boolean,
764
- ) => {
765
- if (
766
- invalidateDependents &&
767
- getFromRangeMap(getQueries(target).get(revision) ?? [], id, count) !== undefined
768
- ) {
769
- table.isInvalidated = true;
770
- }
771
- setInCrossFieldMap(getMap(target), revision, id, count, value);
772
- },
773
-
774
- reset: () => {
775
- table.isInvalidated = false;
776
- table.srcQueries.clear();
777
- table.dstQueries.clear();
778
- },
779
- };
780
-
781
- return table;
782
- }
783
-
784
701
  /**
785
702
  * Splits the `mark` into two marks such that the first returned mark has length `length`.
786
703
  * @param mark - The mark to split.
@@ -969,3 +886,38 @@ export function getEndpoint(effect: MoveMarkEffect): ChangeAtomId {
969
886
  }
970
887
  : { revision: effect.revision, localId: effect.id };
971
888
  }
889
+
890
+ export function getCrossFieldKeys(change: Changeset): CrossFieldKeyRange[] {
891
+ const keys: CrossFieldKeyRange[] = [];
892
+ for (const mark of change) {
893
+ keys.push(...getCrossFieldKeysForMarkEffect(mark, mark.count));
894
+ }
895
+
896
+ return keys;
897
+ }
898
+
899
+ function getCrossFieldKeysForMarkEffect(
900
+ effect: MarkEffect,
901
+ count: number,
902
+ ): CrossFieldKeyRange[] {
903
+ switch (effect.type) {
904
+ case "Insert":
905
+ // An insert behaves like a move where the source and destination are at the same location.
906
+ // An insert can become a move when after rebasing.
907
+ return [
908
+ [CrossFieldTarget.Source, effect.revision, effect.id, count],
909
+ [CrossFieldTarget.Destination, effect.revision, effect.id, count],
910
+ ];
911
+ case "MoveOut":
912
+ return [[CrossFieldTarget.Source, effect.revision, effect.id, count]];
913
+ case "MoveIn":
914
+ return [[CrossFieldTarget.Destination, effect.revision, effect.id, count]];
915
+ case "AttachAndDetach":
916
+ return [
917
+ ...getCrossFieldKeysForMarkEffect(effect.attach, count),
918
+ ...getCrossFieldKeysForMarkEffect(effect.detach, count),
919
+ ];
920
+ default:
921
+ return [];
922
+ }
923
+ }
@@ -19,6 +19,7 @@ import {
19
19
  type TreeStoredSchema,
20
20
  type TreeTypeSet,
21
21
  type ValueSchema,
22
+ identifierFieldKindIdentifier,
22
23
  } from "../../core/index.js";
23
24
  import {
24
25
  type Assume,
@@ -28,6 +29,7 @@ import {
28
29
  mapIterable,
29
30
  oneFromSet,
30
31
  type requireAssignableTo,
32
+ filterIterable,
31
33
  } from "../../util/index.js";
32
34
  import { FieldKinds } from "../default-schema/index.js";
33
35
  import type { FlexFieldKind, FullSchemaPolicy } from "../modular-schema/index.js";
@@ -154,6 +156,7 @@ export class FlexObjectNodeSchema<
154
156
  const out Specification extends Unenforced<FlexObjectNodeFields> = FlexObjectNodeFields,
155
157
  > extends TreeNodeSchemaBase<Name, Specification> {
156
158
  protected _typeCheck2?: MakeNominal;
159
+ public readonly identifierFieldKeys: readonly FieldKey[] = [];
157
160
 
158
161
  public static create<
159
162
  const Name extends string,
@@ -192,6 +195,13 @@ export class FlexObjectNodeSchema<
192
195
  ) {
193
196
  const fields = mapIterable(objectNodeFields, ([k, v]) => [k, v.stored] as const);
194
197
  super(builder, name, info, new ObjectNodeStoredSchema(new Map(fields)));
198
+ this.identifierFieldKeys = Array.from(
199
+ filterIterable(
200
+ objectNodeFields.entries(),
201
+ ([k, f]) => f.kind.identifier === identifierFieldKindIdentifier,
202
+ ),
203
+ ([k]) => k,
204
+ );
195
205
  }
196
206
 
197
207
  public override getFieldSchema(field: FieldKey): FlexFieldSchema {
package/src/index.ts CHANGED
@@ -358,7 +358,6 @@ export {
358
358
  type FlexTreeUnboxField,
359
359
  type FlexTreeUnboxNode,
360
360
  type FlexTreeUnboxNodeUnion,
361
- type FlexTreeNodeKeyField,
362
361
  type IsArrayOfOne,
363
362
  type FlexibleNodeSubSequence,
364
363
  flexTreeMarker,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/tree";
9
- export const pkgVersion = "2.1.0-276985";
9
+ export const pkgVersion = "2.1.0-281041";
@@ -39,7 +39,7 @@ import {
39
39
  mapTreeFromNodeData,
40
40
  prepareContentForHydration,
41
41
  } from "../simple-tree/index.js";
42
- import { disposeSymbol } from "../util/index.js";
42
+ import { Breakable, breakingClass, disposeSymbol, type WithBreakable } from "../util/index.js";
43
43
 
44
44
  import { canInitialize, ensureSchema, initialize } from "./schematizeTree.js";
45
45
  import type { TreeCheckout } from "./treeCheckout.js";
@@ -48,8 +48,9 @@ import { CheckoutFlexTreeView } from "./treeView.js";
48
48
  /**
49
49
  * Implementation of TreeView wrapping a FlexTreeView.
50
50
  */
51
+ @breakingClass
51
52
  export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitFieldSchema>
52
- implements TreeView<TRootSchema>
53
+ implements TreeView<TRootSchema>, WithBreakable
53
54
  {
54
55
  /**
55
56
  * The view is set to undefined when this object is disposed or the view schema does not support viewing the document's stored schema.
@@ -86,6 +87,7 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
86
87
  public readonly checkout: TreeCheckout,
87
88
  public readonly config: TreeViewConfiguration<TRootSchema>,
88
89
  public readonly nodeKeyManager: NodeKeyManager,
90
+ public readonly breaker: Breakable = new Breakable("SchematizingSimpleTreeView"),
89
91
  ) {
90
92
  const policy = {
91
93
  ...defaultSchemaPolicy,
@@ -306,6 +308,7 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
306
308
  }
307
309
 
308
310
  public get root(): TreeFieldFromImplicitField<TRootSchema> {
311
+ this.breaker.use();
309
312
  if (!this.compatibility.canView) {
310
313
  throw new UsageError(
311
314
  "Document is out of schema. Check TreeView.compatibility before accessing TreeView.root.",
@@ -316,6 +319,7 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
316
319
  }
317
320
 
318
321
  public set root(newRoot: InsertableTreeFieldFromImplicitField<TRootSchema>) {
322
+ this.breaker.use();
319
323
  if (!this.compatibility.canView) {
320
324
  throw new UsageError(
321
325
  "Document is out of schema. Check TreeView.compatibility before accessing TreeView.root.",
@@ -64,6 +64,7 @@ import type { SharedTreeChange } from "./sharedTreeChangeTypes.js";
64
64
  import type { SharedTreeEditBuilder } from "./sharedTreeEditBuilder.js";
65
65
  import { type CheckoutEvents, type TreeCheckout, createTreeCheckout } from "./treeCheckout.js";
66
66
  import type { CheckoutFlexTreeView, FlexTreeView } from "./treeView.js";
67
+ import { breakingClass, throwIfBroken } from "../util/index.js";
67
68
 
68
69
  /**
69
70
  * Copy of data from an {@link ISharedTree} at some point in time.
@@ -162,6 +163,7 @@ function getCodecVersions(formatVersion: number): ExplicitCodecVersions {
162
163
  *
163
164
  * TODO: detail compatibility requirements.
164
165
  */
166
+ @breakingClass
165
167
  export class SharedTree
166
168
  extends SharedTreeCore<SharedTreeEditBuilder, SharedTreeChange>
167
169
  implements ISharedTree
@@ -288,6 +290,7 @@ export class SharedTree
288
290
  );
289
291
  }
290
292
 
293
+ @throwIfBroken
291
294
  public contentSnapshot(): SharedTreeContentSnapshot {
292
295
  const cursor = this.checkout.forest.allocateCursor("contentSnapshot");
293
296
  try {
@@ -326,6 +329,7 @@ export class SharedTree
326
329
  this.checkout,
327
330
  config,
328
331
  createNodeKeyManager(this.runtime.idCompressor),
332
+ this.breaker,
329
333
  );
330
334
  }
331
335
 
@@ -572,6 +572,10 @@ export class TreeCheckout implements ITreeCheckoutFork {
572
572
 
573
573
  public rebase(view: TreeCheckout): void {
574
574
  this.checkNotDisposed();
575
+ assert(
576
+ !view.transaction.inProgress(),
577
+ "A view cannot be rebased while it has a pending transaction",
578
+ );
575
579
  view.branch.rebaseOnto(this.branch);
576
580
  }
577
581
 
@@ -585,8 +589,8 @@ export class TreeCheckout implements ITreeCheckoutFork {
585
589
  public merge(view: TreeCheckout, disposeView = true): void {
586
590
  this.checkNotDisposed();
587
591
  assert(
588
- !this.transaction.inProgress() || disposeView,
589
- 0x710 /* A view that is merged into an in-progress transaction must be disposed */,
592
+ !this.transaction.inProgress(),
593
+ "Views cannot be merged into a view while it has a pending transaction",
590
594
  );
591
595
  while (view.transaction.inProgress()) {
592
596
  view.transaction.commit();
@@ -244,6 +244,7 @@ export class SharedTreeBranch<
244
244
  ): [change: TChange, newCommit: GraphCommit<TChange>] {
245
245
  this.assertNotDisposed();
246
246
 
247
+ // TODO: This should not be necessary when receiving changes from other clients.
247
248
  const changeWithRevision = this.changeFamily.rebaser.changeRevision(change, revision);
248
249
 
249
250
  const newHead = mintCommit(this.head, {
@@ -34,7 +34,14 @@ import {
34
34
  type SchemaPolicy,
35
35
  type TreeStoredSchemaRepository,
36
36
  } from "../core/index.js";
37
- import { type JsonCompatibleReadOnly, brand } from "../util/index.js";
37
+ import {
38
+ type JsonCompatibleReadOnly,
39
+ brand,
40
+ Breakable,
41
+ type WithBreakable,
42
+ throwIfBroken,
43
+ breakingClass,
44
+ } from "../util/index.js";
38
45
 
39
46
  import { type SharedTreeBranch, getChangeReplaceType } from "./branch.js";
40
47
  import { EditManager, minimumPossibleSequenceNumber } from "./editManager.js";
@@ -62,12 +69,15 @@ export interface ClonableSchemaAndPolicy extends SchemaAndPolicy {
62
69
  }
63
70
 
64
71
  /**
65
- * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.
66
- *
67
- * TODO: actually implement
68
- * TODO: is history policy a detail of what indexes are used, or is there something else to it?
72
+ * Generic shared tree, which needs to be configured with indexes, field kinds and other configuration.
69
73
  */
70
- export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {
74
+ @breakingClass
75
+ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
76
+ extends SharedObject
77
+ implements WithBreakable
78
+ {
79
+ public readonly breaker: Breakable = new Breakable("Shared Tree");
80
+
71
81
  private readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;
72
82
  private readonly summarizables: readonly Summarizable[];
73
83
  /**
@@ -262,6 +272,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends
262
272
 
263
273
  // TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:
264
274
  // We might want to not subclass it, or override/reimplement most of its functionality.
275
+ @throwIfBroken
265
276
  protected summarizeCore(
266
277
  serializer: IFluidSerializer,
267
278
  telemetryContext?: ITelemetryContext,
@@ -304,6 +315,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends
304
315
  * @returns the submitted commit. This is undefined if the underlying `SharedObject` is not attached,
305
316
  * and may differ from `commit` due to enrichments like detached tree refreshers.
306
317
  */
318
+
307
319
  private submitCommit(
308
320
  commit: GraphCommit<TChange>,
309
321
  schemaAndPolicy: ClonableSchemaAndPolicy,
@@ -19,6 +19,7 @@ import {
19
19
  getOrCreateMapTreeNode,
20
20
  getSchemaAndPolicy,
21
21
  isMapTreeNode,
22
+ isFlexTreeNode,
22
23
  } from "../feature-libraries/index.js";
23
24
  import {
24
25
  type InsertableContent,
@@ -39,7 +40,12 @@ import {
39
40
  normalizeFieldSchema,
40
41
  } from "./schemaTypes.js";
41
42
  import { mapTreeFromNodeData } from "./toMapTree.js";
42
- import { type TreeNode, TreeNodeValid } from "./types.js";
43
+ import {
44
+ type TreeNode,
45
+ TreeNodeValid,
46
+ type InternalTreeNode,
47
+ type MostDerivedData,
48
+ } from "./types.js";
43
49
  import { fail } from "../util/index.js";
44
50
  import { getFlexSchema } from "./toFlexSchema.js";
45
51
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
@@ -215,6 +221,11 @@ export interface TreeArrayNodeBase<out T, in TNew, in TMoveFrom>
215
221
  sourceEnd: number,
216
222
  source: TMoveFrom,
217
223
  ): void;
224
+
225
+ /**
226
+ * Returns a custom IterableIterator which throws usage errors if concurrent editing and iteration occurs.
227
+ */
228
+ values(): IterableIterator<T>;
218
229
  }
219
230
 
220
231
  /**
@@ -315,7 +326,6 @@ const arrayPrototypeKeys = [
315
326
  "some",
316
327
  "toLocaleString",
317
328
  "toString",
318
- "values",
319
329
 
320
330
  // "copyWithin",
321
331
  // "fill",
@@ -489,7 +499,6 @@ declare abstract class NodeWithArrayFeatures<Input, T>
489
499
  ): boolean;
490
500
  toLocaleString(): string;
491
501
  toString(): string;
492
- values(): IterableIterator<T>;
493
502
  }
494
503
  /* eslint-enable @typescript-eslint/explicit-member-accessibility, @typescript-eslint/no-explicit-any */
495
504
 
@@ -554,16 +563,8 @@ function createArrayNodeProxy(
554
563
  return Reflect.get(dispatchTarget, key, receiver) as unknown;
555
564
  }
556
565
 
557
- const value = field.boxedAt(maybeIndex);
558
-
559
- if (value === undefined) {
560
- return undefined;
561
- }
562
-
563
- // TODO: Ideally, we would return leaves without first boxing them. However, this is not
564
- // as simple as calling '.content' since this skips the node and returns the FieldNode's
565
- // inner field.
566
- return getOrCreateNodeProxy(value);
566
+ const maybeContent = field.at(maybeIndex);
567
+ return isFlexTreeNode(maybeContent) ? getOrCreateNodeProxy(maybeContent) : maybeContent;
567
568
  },
568
569
  set: (target, key, newValue, receiver) => {
569
570
  if (key === "length") {
@@ -590,7 +591,7 @@ function createArrayNodeProxy(
590
591
  "Cannot set indexed properties on array nodes. Use array node mutation APIs to alter the array.",
591
592
  );
592
593
  }
593
- return allowAdditionalProperties ? Reflect.set(target, key, newValue) : false;
594
+ return allowAdditionalProperties ? Reflect.set(target, key, newValue, receiver) : false;
594
595
  },
595
596
  has: (target, key) => {
596
597
  const field = getSequenceField(proxy);
@@ -672,6 +673,21 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
672
673
 
673
674
  protected abstract get simpleSchema(): T;
674
675
 
676
+ /**
677
+ * Generation number which is incremented any time we have an edit on the node.
678
+ * Used during iteration to make sure there has been no edits that were concurrently made.
679
+ */
680
+ #generationNumber: number = 0;
681
+
682
+ public constructor(
683
+ input: Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>> | InternalTreeNode,
684
+ ) {
685
+ super(input);
686
+ getFlexNode(this).on("nodeChanged", () => {
687
+ this.#generationNumber += 1;
688
+ });
689
+ }
690
+
675
691
  #cursorFromFieldData(value: Insertable<T>): ITreeCursorSynchronous {
676
692
  if (isMapTreeNode(getFlexNode(this))) {
677
693
  throw new UsageError(`An array cannot be mutated before being inserted into the tree`);
@@ -827,13 +843,7 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
827
843
  const destinationField = getSequenceField(this);
828
844
  validateIndex(destinationIndex, destinationField, "moveRangeToIndex", true);
829
845
  validateIndexRange(sourceStart, sourceEnd, source ?? destinationField, "moveRangeToIndex");
830
- const sourceField =
831
- source !== undefined
832
- ? destinationField.isSameAs(getSequenceField(source))
833
- ? destinationField
834
- : getSequenceField(source)
835
- : destinationField;
836
-
846
+ const sourceField = source !== undefined ? getSequenceField(source) : destinationField;
837
847
  // TODO: determine support for move across different sequence types
838
848
  if (destinationField.schema.types !== undefined && sourceField !== destinationField) {
839
849
  for (let i = sourceStart; i < sourceEnd; i++) {
@@ -855,6 +865,23 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
855
865
  destinationIndex,
856
866
  );
857
867
  }
868
+
869
+ public values(): IterableIterator<TreeNodeFromImplicitAllowedTypes<T>> {
870
+ return this.generateValues(this.#generationNumber);
871
+ }
872
+ private *generateValues(
873
+ initialLastUpdatedStamp: number,
874
+ ): Generator<TreeNodeFromImplicitAllowedTypes<T>> {
875
+ if (initialLastUpdatedStamp !== this.#generationNumber) {
876
+ throw new UsageError(`Concurrent editing and iteration is not allowed.`);
877
+ }
878
+ for (let i = 0; i < this.length; i++) {
879
+ yield this.at(i) ?? fail("Index is out of bounds");
880
+ if (initialLastUpdatedStamp !== this.#generationNumber) {
881
+ throw new UsageError(`Concurrent editing and iteration is not allowed.`);
882
+ }
883
+ }
884
+ }
858
885
  }
859
886
 
860
887
  /**
@@ -921,7 +948,7 @@ export function arraySchema<
921
948
  );
922
949
  }
923
950
 
924
- protected static override constructorCached: typeof TreeNodeValid | undefined = undefined;
951
+ protected static override constructorCached: MostDerivedData | undefined = undefined;
925
952
 
926
953
  protected static override oneTimeSetup<T2>(this: typeof TreeNodeValid<T2>): void {
927
954
  flexSchema = getFlexSchema(this as unknown as TreeNodeSchema) as FlexFieldNodeSchema;