@fluidframework/tree 2.5.0-302463 → 2.5.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 (365) hide show
  1. package/.vscode/settings.json +1 -0
  2. package/CHANGELOG.md +371 -0
  3. package/api-report/tree.alpha.api.md +151 -57
  4. package/api-report/tree.beta.api.md +29 -25
  5. package/api-report/tree.legacy.alpha.api.md +28 -24
  6. package/api-report/tree.legacy.public.api.md +28 -24
  7. package/api-report/tree.public.api.md +28 -24
  8. package/dist/alpha.d.ts +15 -0
  9. package/dist/codec/codec.d.ts +24 -0
  10. package/dist/codec/codec.d.ts.map +1 -1
  11. package/dist/codec/codec.js +26 -1
  12. package/dist/codec/codec.js.map +1 -1
  13. package/dist/codec/index.d.ts +1 -1
  14. package/dist/codec/index.d.ts.map +1 -1
  15. package/dist/codec/index.js +2 -1
  16. package/dist/codec/index.js.map +1 -1
  17. package/dist/core/rebase/index.d.ts +2 -2
  18. package/dist/core/rebase/index.d.ts.map +1 -1
  19. package/dist/core/rebase/index.js +2 -2
  20. package/dist/core/rebase/index.js.map +1 -1
  21. package/dist/core/rebase/types.d.ts +0 -4
  22. package/dist/core/rebase/types.d.ts.map +1 -1
  23. package/dist/core/rebase/types.js +1 -7
  24. package/dist/core/rebase/types.js.map +1 -1
  25. package/dist/core/rebase/utils.d.ts +1 -0
  26. package/dist/core/rebase/utils.d.ts.map +1 -1
  27. package/dist/core/rebase/utils.js +29 -4
  28. package/dist/core/rebase/utils.js.map +1 -1
  29. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +8 -1
  30. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  31. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  32. package/dist/feature-libraries/flex-tree/lazyNode.d.ts +2 -1
  33. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  34. package/dist/feature-libraries/flex-tree/lazyNode.js +3 -0
  35. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  36. package/dist/index.d.ts +3 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +12 -6
  39. package/dist/index.js.map +1 -1
  40. package/dist/packageVersion.d.ts +1 -1
  41. package/dist/packageVersion.d.ts.map +1 -1
  42. package/dist/packageVersion.js +1 -1
  43. package/dist/packageVersion.js.map +1 -1
  44. package/dist/shared-tree/independentView.d.ts +57 -0
  45. package/dist/shared-tree/independentView.d.ts.map +1 -0
  46. package/dist/shared-tree/independentView.js +89 -0
  47. package/dist/shared-tree/independentView.js.map +1 -0
  48. package/dist/shared-tree/index.d.ts +3 -1
  49. package/dist/shared-tree/index.d.ts.map +1 -1
  50. package/dist/shared-tree/index.js +6 -1
  51. package/dist/shared-tree/index.js.map +1 -1
  52. package/dist/shared-tree/schematizingTreeView.d.ts +12 -8
  53. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  54. package/dist/shared-tree/schematizingTreeView.js +28 -0
  55. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  56. package/dist/shared-tree/sharedTree.d.ts +10 -7
  57. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  58. package/dist/shared-tree/sharedTree.js.map +1 -1
  59. package/dist/shared-tree/treeApiAlpha.d.ts +147 -0
  60. package/dist/shared-tree/treeApiAlpha.d.ts.map +1 -0
  61. package/dist/shared-tree/treeApiAlpha.js +122 -0
  62. package/dist/shared-tree/treeApiAlpha.js.map +1 -0
  63. package/dist/shared-tree/treeCheckout.d.ts +12 -7
  64. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  65. package/dist/shared-tree/treeCheckout.js +9 -4
  66. package/dist/shared-tree/treeCheckout.js.map +1 -1
  67. package/dist/shared-tree-core/editManager.d.ts +13 -6
  68. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  69. package/dist/shared-tree-core/editManager.js +70 -28
  70. package/dist/shared-tree-core/editManager.js.map +1 -1
  71. package/dist/shared-tree-core/sharedTreeCore.d.ts +1 -0
  72. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  73. package/dist/shared-tree-core/sharedTreeCore.js +28 -3
  74. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  75. package/dist/simple-tree/api/conciseTree.d.ts +2 -1
  76. package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
  77. package/dist/simple-tree/api/conciseTree.js.map +1 -1
  78. package/dist/simple-tree/api/create.d.ts +5 -23
  79. package/dist/simple-tree/api/create.d.ts.map +1 -1
  80. package/dist/simple-tree/api/create.js +4 -19
  81. package/dist/simple-tree/api/create.js.map +1 -1
  82. package/dist/simple-tree/api/customTree.d.ts +1 -0
  83. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  84. package/dist/simple-tree/api/customTree.js.map +1 -1
  85. package/dist/simple-tree/api/index.d.ts +5 -5
  86. package/dist/simple-tree/api/index.d.ts.map +1 -1
  87. package/dist/simple-tree/api/index.js +10 -1
  88. package/dist/simple-tree/api/index.js.map +1 -1
  89. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +6 -16
  90. package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  91. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  92. package/dist/simple-tree/api/schemaFactory.d.ts +11 -11
  93. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  94. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  95. package/dist/simple-tree/api/storedSchema.js +2 -2
  96. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  97. package/dist/simple-tree/api/testRecursiveDomain.d.ts +5 -5
  98. package/dist/simple-tree/api/tree.d.ts +115 -7
  99. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  100. package/dist/simple-tree/api/tree.js +12 -4
  101. package/dist/simple-tree/api/tree.js.map +1 -1
  102. package/dist/simple-tree/api/treeApiBeta.d.ts +8 -5
  103. package/dist/simple-tree/api/treeApiBeta.d.ts.map +1 -1
  104. package/dist/simple-tree/api/treeApiBeta.js +3 -15
  105. package/dist/simple-tree/api/treeApiBeta.js.map +1 -1
  106. package/dist/simple-tree/api/typesUnsafe.d.ts +1 -1
  107. package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  108. package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
  109. package/dist/simple-tree/api/verboseTree.d.ts +3 -0
  110. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  111. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  112. package/dist/simple-tree/arrayNode.d.ts +1 -1
  113. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  114. package/dist/simple-tree/arrayNode.js +1 -1
  115. package/dist/simple-tree/arrayNode.js.map +1 -1
  116. package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
  117. package/dist/simple-tree/core/treeNodeSchema.d.ts +45 -9
  118. package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  119. package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
  120. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +2 -1
  121. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  122. package/dist/simple-tree/core/unhydratedFlexTree.js +3 -0
  123. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  124. package/dist/simple-tree/core/withType.d.ts +1 -2
  125. package/dist/simple-tree/core/withType.d.ts.map +1 -1
  126. package/dist/simple-tree/core/withType.js.map +1 -1
  127. package/dist/simple-tree/createContext.js +2 -2
  128. package/dist/simple-tree/createContext.js.map +1 -1
  129. package/dist/simple-tree/index.d.ts +4 -4
  130. package/dist/simple-tree/index.d.ts.map +1 -1
  131. package/dist/simple-tree/index.js +15 -4
  132. package/dist/simple-tree/index.js.map +1 -1
  133. package/dist/simple-tree/leafNodeSchema.d.ts +6 -5
  134. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  135. package/dist/simple-tree/leafNodeSchema.js +3 -0
  136. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  137. package/dist/simple-tree/mapNode.d.ts +1 -1
  138. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  139. package/dist/simple-tree/mapNode.js +3 -0
  140. package/dist/simple-tree/mapNode.js.map +1 -1
  141. package/dist/simple-tree/schemaTypes.d.ts +45 -7
  142. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  143. package/dist/simple-tree/schemaTypes.js +61 -1
  144. package/dist/simple-tree/schemaTypes.js.map +1 -1
  145. package/dist/simple-tree/{toFlexSchema.d.ts → toStoredSchema.d.ts} +1 -1
  146. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -0
  147. package/dist/simple-tree/{toFlexSchema.js → toStoredSchema.js} +1 -1
  148. package/dist/simple-tree/toStoredSchema.js.map +1 -0
  149. package/dist/simple-tree/treeNodeValid.d.ts +5 -1
  150. package/dist/simple-tree/treeNodeValid.d.ts.map +1 -1
  151. package/dist/simple-tree/treeNodeValid.js +7 -1
  152. package/dist/simple-tree/treeNodeValid.js.map +1 -1
  153. package/dist/util/index.d.ts +1 -1
  154. package/dist/util/index.d.ts.map +1 -1
  155. package/dist/util/index.js.map +1 -1
  156. package/dist/util/typeCheck.d.ts +9 -0
  157. package/dist/util/typeCheck.d.ts.map +1 -1
  158. package/dist/util/typeCheck.js.map +1 -1
  159. package/dist/util/utils.d.ts +7 -3
  160. package/dist/util/utils.d.ts.map +1 -1
  161. package/dist/util/utils.js +13 -3
  162. package/dist/util/utils.js.map +1 -1
  163. package/lib/alpha.d.ts +15 -0
  164. package/lib/codec/codec.d.ts +24 -0
  165. package/lib/codec/codec.d.ts.map +1 -1
  166. package/lib/codec/codec.js +25 -0
  167. package/lib/codec/codec.js.map +1 -1
  168. package/lib/codec/index.d.ts +1 -1
  169. package/lib/codec/index.d.ts.map +1 -1
  170. package/lib/codec/index.js +1 -1
  171. package/lib/codec/index.js.map +1 -1
  172. package/lib/core/rebase/index.d.ts +2 -2
  173. package/lib/core/rebase/index.d.ts.map +1 -1
  174. package/lib/core/rebase/index.js +2 -2
  175. package/lib/core/rebase/index.js.map +1 -1
  176. package/lib/core/rebase/types.d.ts +0 -4
  177. package/lib/core/rebase/types.d.ts.map +1 -1
  178. package/lib/core/rebase/types.js +0 -5
  179. package/lib/core/rebase/types.js.map +1 -1
  180. package/lib/core/rebase/utils.d.ts +1 -0
  181. package/lib/core/rebase/utils.d.ts.map +1 -1
  182. package/lib/core/rebase/utils.js +27 -3
  183. package/lib/core/rebase/utils.js.map +1 -1
  184. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +8 -1
  185. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  186. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  187. package/lib/feature-libraries/flex-tree/lazyNode.d.ts +2 -1
  188. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  189. package/lib/feature-libraries/flex-tree/lazyNode.js +3 -0
  190. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  191. package/lib/index.d.ts +3 -3
  192. package/lib/index.d.ts.map +1 -1
  193. package/lib/index.js +3 -2
  194. package/lib/index.js.map +1 -1
  195. package/lib/packageVersion.d.ts +1 -1
  196. package/lib/packageVersion.d.ts.map +1 -1
  197. package/lib/packageVersion.js +1 -1
  198. package/lib/packageVersion.js.map +1 -1
  199. package/lib/shared-tree/independentView.d.ts +57 -0
  200. package/lib/shared-tree/independentView.d.ts.map +1 -0
  201. package/lib/shared-tree/independentView.js +84 -0
  202. package/lib/shared-tree/independentView.js.map +1 -0
  203. package/lib/shared-tree/index.d.ts +3 -1
  204. package/lib/shared-tree/index.d.ts.map +1 -1
  205. package/lib/shared-tree/index.js +2 -0
  206. package/lib/shared-tree/index.js.map +1 -1
  207. package/lib/shared-tree/schematizingTreeView.d.ts +12 -8
  208. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  209. package/lib/shared-tree/schematizingTreeView.js +29 -1
  210. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  211. package/lib/shared-tree/sharedTree.d.ts +10 -7
  212. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  213. package/lib/shared-tree/sharedTree.js.map +1 -1
  214. package/lib/shared-tree/treeApiAlpha.d.ts +147 -0
  215. package/lib/shared-tree/treeApiAlpha.d.ts.map +1 -0
  216. package/lib/shared-tree/treeApiAlpha.js +119 -0
  217. package/lib/shared-tree/treeApiAlpha.js.map +1 -0
  218. package/lib/shared-tree/treeCheckout.d.ts +12 -7
  219. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  220. package/lib/shared-tree/treeCheckout.js +9 -4
  221. package/lib/shared-tree/treeCheckout.js.map +1 -1
  222. package/lib/shared-tree-core/editManager.d.ts +13 -6
  223. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  224. package/lib/shared-tree-core/editManager.js +70 -28
  225. package/lib/shared-tree-core/editManager.js.map +1 -1
  226. package/lib/shared-tree-core/sharedTreeCore.d.ts +1 -0
  227. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  228. package/lib/shared-tree-core/sharedTreeCore.js +29 -4
  229. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  230. package/lib/simple-tree/api/conciseTree.d.ts +2 -1
  231. package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
  232. package/lib/simple-tree/api/conciseTree.js.map +1 -1
  233. package/lib/simple-tree/api/create.d.ts +5 -23
  234. package/lib/simple-tree/api/create.d.ts.map +1 -1
  235. package/lib/simple-tree/api/create.js +2 -16
  236. package/lib/simple-tree/api/create.js.map +1 -1
  237. package/lib/simple-tree/api/customTree.d.ts +1 -0
  238. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  239. package/lib/simple-tree/api/customTree.js.map +1 -1
  240. package/lib/simple-tree/api/index.d.ts +5 -5
  241. package/lib/simple-tree/api/index.d.ts.map +1 -1
  242. package/lib/simple-tree/api/index.js +5 -3
  243. package/lib/simple-tree/api/index.js.map +1 -1
  244. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +6 -16
  245. package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  246. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  247. package/lib/simple-tree/api/schemaFactory.d.ts +11 -11
  248. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  249. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  250. package/lib/simple-tree/api/storedSchema.js +1 -1
  251. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  252. package/lib/simple-tree/api/testRecursiveDomain.d.ts +5 -5
  253. package/lib/simple-tree/api/tree.d.ts +115 -7
  254. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  255. package/lib/simple-tree/api/tree.js +9 -2
  256. package/lib/simple-tree/api/tree.js.map +1 -1
  257. package/lib/simple-tree/api/treeApiBeta.d.ts +8 -5
  258. package/lib/simple-tree/api/treeApiBeta.d.ts.map +1 -1
  259. package/lib/simple-tree/api/treeApiBeta.js +4 -16
  260. package/lib/simple-tree/api/treeApiBeta.js.map +1 -1
  261. package/lib/simple-tree/api/typesUnsafe.d.ts +1 -1
  262. package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  263. package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
  264. package/lib/simple-tree/api/verboseTree.d.ts +3 -0
  265. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  266. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  267. package/lib/simple-tree/arrayNode.d.ts +1 -1
  268. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  269. package/lib/simple-tree/arrayNode.js +1 -1
  270. package/lib/simple-tree/arrayNode.js.map +1 -1
  271. package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
  272. package/lib/simple-tree/core/treeNodeSchema.d.ts +45 -9
  273. package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  274. package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
  275. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +2 -1
  276. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  277. package/lib/simple-tree/core/unhydratedFlexTree.js +4 -1
  278. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  279. package/lib/simple-tree/core/withType.d.ts +1 -2
  280. package/lib/simple-tree/core/withType.d.ts.map +1 -1
  281. package/lib/simple-tree/core/withType.js.map +1 -1
  282. package/lib/simple-tree/createContext.js +1 -1
  283. package/lib/simple-tree/createContext.js.map +1 -1
  284. package/lib/simple-tree/index.d.ts +4 -4
  285. package/lib/simple-tree/index.d.ts.map +1 -1
  286. package/lib/simple-tree/index.js +4 -4
  287. package/lib/simple-tree/index.js.map +1 -1
  288. package/lib/simple-tree/leafNodeSchema.d.ts +6 -5
  289. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  290. package/lib/simple-tree/leafNodeSchema.js +3 -0
  291. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  292. package/lib/simple-tree/mapNode.d.ts +1 -1
  293. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  294. package/lib/simple-tree/mapNode.js +3 -0
  295. package/lib/simple-tree/mapNode.js.map +1 -1
  296. package/lib/simple-tree/schemaTypes.d.ts +45 -7
  297. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  298. package/lib/simple-tree/schemaTypes.js +59 -1
  299. package/lib/simple-tree/schemaTypes.js.map +1 -1
  300. package/lib/simple-tree/{toFlexSchema.d.ts → toStoredSchema.d.ts} +1 -1
  301. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -0
  302. package/lib/simple-tree/{toFlexSchema.js → toStoredSchema.js} +1 -1
  303. package/lib/simple-tree/toStoredSchema.js.map +1 -0
  304. package/lib/simple-tree/treeNodeValid.d.ts +5 -1
  305. package/lib/simple-tree/treeNodeValid.d.ts.map +1 -1
  306. package/lib/simple-tree/treeNodeValid.js +7 -1
  307. package/lib/simple-tree/treeNodeValid.js.map +1 -1
  308. package/lib/util/index.d.ts +1 -1
  309. package/lib/util/index.d.ts.map +1 -1
  310. package/lib/util/index.js.map +1 -1
  311. package/lib/util/typeCheck.d.ts +9 -0
  312. package/lib/util/typeCheck.d.ts.map +1 -1
  313. package/lib/util/typeCheck.js.map +1 -1
  314. package/lib/util/utils.d.ts +7 -3
  315. package/lib/util/utils.d.ts.map +1 -1
  316. package/lib/util/utils.js +13 -3
  317. package/lib/util/utils.js.map +1 -1
  318. package/package.json +30 -21
  319. package/src/codec/codec.ts +25 -0
  320. package/src/codec/index.ts +1 -0
  321. package/src/core/rebase/index.ts +1 -1
  322. package/src/core/rebase/types.ts +0 -12
  323. package/src/core/rebase/utils.ts +35 -3
  324. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +9 -0
  325. package/src/feature-libraries/flex-tree/lazyNode.ts +5 -0
  326. package/src/index.ts +20 -5
  327. package/src/packageVersion.ts +1 -1
  328. package/src/shared-tree/independentView.ts +176 -0
  329. package/src/shared-tree/index.ts +9 -1
  330. package/src/shared-tree/schematizingTreeView.ts +58 -11
  331. package/src/shared-tree/sharedTree.ts +29 -11
  332. package/src/shared-tree/treeApiAlpha.ts +401 -0
  333. package/src/shared-tree/treeCheckout.ts +26 -5
  334. package/src/shared-tree-core/editManager.ts +112 -54
  335. package/src/shared-tree-core/sharedTreeCore.ts +37 -8
  336. package/src/simple-tree/api/conciseTree.ts +2 -1
  337. package/src/simple-tree/api/create.ts +21 -58
  338. package/src/simple-tree/api/customTree.ts +1 -0
  339. package/src/simple-tree/api/index.ts +13 -7
  340. package/src/simple-tree/api/schemaCreationUtilities.ts +4 -5
  341. package/src/simple-tree/api/schemaFactory.ts +24 -12
  342. package/src/simple-tree/api/storedSchema.ts +1 -1
  343. package/src/simple-tree/api/tree.ts +136 -14
  344. package/src/simple-tree/api/treeApiBeta.ts +35 -35
  345. package/src/simple-tree/api/typesUnsafe.ts +1 -2
  346. package/src/simple-tree/api/verboseTree.ts +3 -0
  347. package/src/simple-tree/arrayNode.ts +4 -3
  348. package/src/simple-tree/core/getOrCreateNode.ts +1 -1
  349. package/src/simple-tree/core/treeNodeSchema.ts +99 -31
  350. package/src/simple-tree/core/unhydratedFlexTree.ts +6 -0
  351. package/src/simple-tree/core/withType.ts +1 -9
  352. package/src/simple-tree/createContext.ts +1 -1
  353. package/src/simple-tree/index.ts +15 -1
  354. package/src/simple-tree/leafNodeSchema.ts +6 -1
  355. package/src/simple-tree/mapNode.ts +7 -1
  356. package/src/simple-tree/schemaTypes.ts +128 -14
  357. package/src/simple-tree/treeNodeValid.ts +11 -1
  358. package/src/util/index.ts +1 -0
  359. package/src/util/typeCheck.ts +13 -0
  360. package/src/util/utils.ts +20 -7
  361. package/dist/simple-tree/toFlexSchema.d.ts.map +0 -1
  362. package/dist/simple-tree/toFlexSchema.js.map +0 -1
  363. package/lib/simple-tree/toFlexSchema.d.ts.map +0 -1
  364. package/lib/simple-tree/toFlexSchema.js.map +0 -1
  365. /package/src/simple-tree/{toFlexSchema.ts → toStoredSchema.ts} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  import type { Format } from "../../feature-libraries/schema-index/index.js";
15
15
  import type { JsonCompatible } from "../../util/index.js";
16
16
  import type { ImplicitFieldSchema } from "../schemaTypes.js";
17
- import { toStoredSchema } from "../toFlexSchema.js";
17
+ import { toStoredSchema } from "../toStoredSchema.js";
18
18
  import type { SchemaCompatibilityStatus } from "./tree.js";
19
19
  import { ViewSchema } from "./view.js";
20
20
 
@@ -13,13 +13,14 @@ import {
13
13
  type ImplicitFieldSchema,
14
14
  type InsertableField,
15
15
  type InsertableTreeFieldFromImplicitField,
16
+ type ReadableField,
17
+ type ReadSchema,
16
18
  type TreeFieldFromImplicitField,
17
- type TreeLeafValue,
18
19
  type UnsafeUnknownSchema,
19
20
  FieldKind,
20
21
  } from "../schemaTypes.js";
21
- import { NodeKind, type TreeNode, type TreeNodeSchema } from "../core/index.js";
22
- import { toStoredSchema } from "../toFlexSchema.js";
22
+ import { NodeKind, type TreeNodeSchema } from "../core/index.js";
23
+ import { toStoredSchema } from "../toStoredSchema.js";
23
24
  import { LeafNodeSchema } from "../leafNodeSchema.js";
24
25
  import { assert } from "@fluidframework/core-utils/internal";
25
26
  import { isObjectNodeSchema, type ObjectNodeSchema } from "../objectNodeTypes.js";
@@ -29,6 +30,14 @@ import type { MakeNominal } from "../../util/index.js";
29
30
  import { walkFieldSchema } from "../walkFieldSchema.js";
30
31
  /**
31
32
  * A tree from which a {@link TreeView} can be created.
33
+ *
34
+ * @privateRemarks
35
+ * TODO:
36
+ * Add stored key versions of {@link TreeAlpha.(exportVerbose:2)}, {@link TreeAlpha.(exportConcise:2)} and {@link TreeAlpha.exportCompressed} here so tree content can be accessed without a view schema.
37
+ * Add exportSimpleSchema and exportJsonSchema methods (which should exactly match the concise format, and match the free functions for exporting view schema).
38
+ * Maybe rename "exportJsonSchema" to align on "concise" terminology.
39
+ * Ensure schema exporting APIs here align and reference APIs for exporting view schema to the same formats (which should include stored vs property key choice).
40
+ * Make sure users of independentView can use these export APIs (maybe provide a reference back to the ViewableTree from the TreeView to accomplish that).
32
41
  * @system @sealed @public
33
42
  */
34
43
  export interface ViewableTree {
@@ -48,7 +57,7 @@ export interface ViewableTree {
48
57
  * Only one schematized view may exist for a given ITree at a time.
49
58
  * If creating a second, the first must be disposed before calling `viewWith` again.
50
59
  *
51
- * @privateRemarks
60
+ *
52
61
  * TODO: Provide a way to make a generic view schema for any document.
53
62
  * TODO: Support adapters for handling out-of-schema data.
54
63
  *
@@ -242,7 +251,7 @@ export class TreeViewConfiguration<
242
251
  if (ambiguityErrors.length !== 0) {
243
252
  // Duplicate errors are common since when two types conflict, both orders error:
244
253
  const deduplicated = new Set(ambiguityErrors);
245
- throw new UsageError(`Ambigious schema found:\n${[...deduplicated].join("\n")}`);
254
+ throw new UsageError(`Ambiguous schema found:\n${[...deduplicated].join("\n")}`);
246
255
  }
247
256
 
248
257
  // Eagerly perform this conversion to surface errors sooner.
@@ -350,6 +359,84 @@ export function checkUnion(union: Iterable<TreeNodeSchema>, errors: string[]): v
350
359
  }
351
360
  }
352
361
 
362
+ /**
363
+ * A collection of functionality associated with a (version-control-style) branch of a SharedTree.
364
+ * @remarks A `TreeBranch` allows for the {@link TreeBranch.fork | creation of branches} and for those branches to later be {@link TreeBranch.merge | merged}.
365
+ *
366
+ * The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.
367
+ *
368
+ * A branch does not necessarily know the schema of its SharedTree - to convert a branch to a {@link TreeViewAlpha | view with a schema}, use {@link TreeBranch.hasRootSchema | hasRootSchema()}.
369
+ *
370
+ * The branch associated directly with the {@link ITree | SharedTree} is the "main" branch, and all other branches fork (directly or transitively) from that main branch.
371
+ * @sealed @alpha
372
+ */
373
+ export interface TreeBranch extends IDisposable {
374
+ /**
375
+ * Events for the branch
376
+ */
377
+ readonly events: Listenable<TreeBranchEvents>;
378
+
379
+ /**
380
+ * Returns true if this branch has the given schema as its root schema.
381
+ * @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.
382
+ *
383
+ * To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.
384
+ * For example, a schema of `Foo | Bar` will not match a view schema of `Foo`, and likewise a schema of `Foo` will not match a view schema of `Foo | Bar`.
385
+ * @example
386
+ * ```typescript
387
+ * if (branch.hasRootSchema(MySchema)) {
388
+ * const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>
389
+ * // ...
390
+ * }
391
+ * ```
392
+ */
393
+ hasRootSchema<TSchema extends ImplicitFieldSchema>(
394
+ schema: TSchema,
395
+ ): this is TreeViewAlpha<TSchema>;
396
+
397
+ /**
398
+ * Fork a new branch off of this branch which is based off of this branch's current state.
399
+ * @remarks Any changes to the tree on the new branch will not apply to this branch until the new branch is e.g. {@link TreeBranch.merge | merged} back into this branch.
400
+ * The branch should be disposed when no longer needed, either {@link TreeBranch.dispose | explicitly} or {@link TreeBranch.merge | implicitly when merging} into another branch.
401
+ */
402
+ fork(): TreeBranch;
403
+
404
+ /**
405
+ * Apply all the new changes on the given branch to this branch.
406
+ * @param branch - a branch which was created by a call to `branch()`.
407
+ * @param disposeMerged - whether or not to dispose `branch` after the merge completes.
408
+ * Defaults to true.
409
+ * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.
410
+ * @remarks All ongoing transactions (if any) in `branch` will be committed before the merge.
411
+ */
412
+ merge(branch: TreeBranch, disposeMerged?: boolean): void;
413
+
414
+ /**
415
+ * Advance this branch forward such that all new changes on the target branch become part of this branch.
416
+ * @param branch - The branch to rebase onto.
417
+ * @remarks After rebasing, this branch will be "ahead" of the target branch, that is, its unique changes will have been recreated as if they happened after all changes on the target branch.
418
+ * This method may only be called on branches produced via {@link TreeBranch.fork | branch} - attempting to rebase the main branch will throw.
419
+ *
420
+ * Rebasing long-lived branches is important to avoid consuming memory unnecessarily.
421
+ * In particular, the SharedTree retains all sequenced changes made to the tree since the "most-behind" branch was created or last rebased.
422
+ *
423
+ * The {@link TreeBranch | main branch} cannot be rebased onto another branch - attempting to do so will throw an error.
424
+ */
425
+ rebaseOnto(branch: TreeBranch): void;
426
+
427
+ /**
428
+ * Dispose of this branch, cleaning up any resources associated with it.
429
+ * @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.
430
+ * @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.
431
+ *
432
+ * Disposing branches is important to avoid consuming memory unnecessarily.
433
+ * In particular, the SharedTree retains all sequenced changes made to the tree since the "most-behind" branch was created or last {@link TreeBranch.rebaseOnto | rebased}.
434
+ *
435
+ * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.
436
+ */
437
+ dispose(error?: Error): void;
438
+ }
439
+
353
440
  /**
354
441
  * An editable view of a (version control style) branch of a shared tree based on some schema.
355
442
  *
@@ -430,21 +517,20 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
430
517
 
431
518
  /**
432
519
  * {@link TreeView} with proposed changes to the schema aware typing to allow use with `UnsafeUnknownSchema`.
433
- * @alpha
520
+ * @sealed @alpha
434
521
  */
435
522
  export interface TreeViewAlpha<
436
523
  in out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,
437
- > extends Omit<
438
- TreeView<TSchema extends ImplicitFieldSchema ? TSchema : ImplicitFieldSchema>,
439
- "root" | "initialize"
440
- > {
441
- get root(): TSchema extends ImplicitFieldSchema
442
- ? TreeFieldFromImplicitField<TSchema>
443
- : TreeLeafValue | TreeNode;
524
+ > extends Omit<TreeView<ReadSchema<TSchema>>, "root" | "initialize">,
525
+ Omit<TreeBranch, "events"> {
526
+ get root(): ReadableField<TSchema>;
444
527
 
445
528
  set root(newRoot: InsertableField<TSchema>);
446
529
 
447
530
  initialize(content: InsertableField<TSchema>): void;
531
+
532
+ // Override the base branch method to return a typed view rather than merely a branch.
533
+ fork(): ReturnType<TreeBranch["fork"]> & TreeViewAlpha<TSchema>;
448
534
  }
449
535
 
450
536
  /**
@@ -514,7 +600,7 @@ export interface SchemaCompatibilityStatus {
514
600
  *
515
601
  * @remarks
516
602
  * It's not necessary to check this field before calling {@link TreeView.initialize} in most scenarios; application authors typically know from
517
- * context that they're in a flow which creates a new `SharedTree` and would like to initialize it.
603
+ * branch that they're in a flow which creates a new `SharedTree` and would like to initialize it.
518
604
  */
519
605
  readonly canInitialize: boolean;
520
606
 
@@ -523,6 +609,32 @@ export interface SchemaCompatibilityStatus {
523
609
  // - details about the differences between the stored and view schema sufficient for implementing "safe mismatch" policies
524
610
  }
525
611
 
612
+ /**
613
+ * Events for {@link TreeBranch}.
614
+ * @sealed @alpha
615
+ */
616
+ export interface TreeBranchEvents {
617
+ /**
618
+ * The stored schema for the document has changed.
619
+ */
620
+ schemaChanged(): void;
621
+
622
+ /**
623
+ * Fired when:
624
+ * - a local commit is applied outside of a transaction
625
+ * - a local transaction is committed
626
+ *
627
+ * The event is not fired when:
628
+ * - a local commit is applied within a transaction
629
+ * - a remote commit is applied
630
+ *
631
+ * @param data - information about the commit that was applied
632
+ * @param getRevertible - a function provided that allows users to get a revertible for the commit that was applied. If not provided,
633
+ * this commit is not revertible.
634
+ */
635
+ commitApplied(data: CommitMetadata, getRevertible?: RevertibleFactory): void;
636
+ }
637
+
526
638
  /**
527
639
  * Events for {@link TreeView}.
528
640
  * @sealed @public
@@ -562,3 +674,13 @@ export interface TreeViewEvents {
562
674
  */
563
675
  commitApplied(data: CommitMetadata, getRevertible?: RevertibleFactory): void;
564
676
  }
677
+
678
+ /**
679
+ * Retrieve the {@link TreeViewAlpha | alpha API} for a {@link TreeView}.
680
+ * @alpha
681
+ */
682
+ export function asTreeViewAlpha<TSchema extends ImplicitFieldSchema>(
683
+ view: TreeView<TSchema>,
684
+ ): TreeViewAlpha<TSchema> {
685
+ return view as TreeViewAlpha<TSchema>;
686
+ }
@@ -12,14 +12,9 @@ import {
12
12
  type Unhydrated,
13
13
  type WithType,
14
14
  } from "../core/index.js";
15
- import type {
16
- ImplicitFieldSchema,
17
- TreeFieldFromImplicitField,
18
- UnsafeUnknownSchema,
19
- } from "../schemaTypes.js";
20
15
  import { treeNodeApi } from "./treeNodeApi.js";
21
- import { createFromCursor, cursorFromInsertable } from "./create.js";
22
- import type { ITreeCursorSynchronous } from "../../core/index.js";
16
+ import { createFromCursor } from "./create.js";
17
+ import type { ImplicitFieldSchema, TreeFieldFromImplicitField } from "../schemaTypes.js";
23
18
 
24
19
  /**
25
20
  * Data included for {@link TreeChangeEventsBeta.nodeChanged}.
@@ -113,18 +108,40 @@ export const TreeBeta: {
113
108
  ): () => void;
114
109
 
115
110
  /**
116
- * Clones the persisted data associated with a node. Some key things to note:
111
+ * Clones the persisted data associated with a node.
112
+ *
113
+ * @param node - The node to clone.
114
+ * @returns A new unhydrated node with the same persisted data as the original node.
115
+ * @remarks
116
+ * Some key things to note:
117
+ *
117
118
  * - Local state, such as properties added to customized schema classes, will not be cloned. However, they will be
118
119
  * initialized to their default state just as if the node had been created via its constructor.
119
120
  * - Value node types (i.e., numbers, strings, booleans, nulls and Fluid handles) will be returned as is.
120
121
  * - The identifiers in the node's subtree will be preserved, i.e., they are not replaced with new values.
121
- *
122
- * @param node - The node to clone.
123
- * @returns A new unhydrated node with the same persisted data as the original node.
124
122
  */
125
- clone<TSchema extends ImplicitFieldSchema>(
123
+ clone<const TSchema extends ImplicitFieldSchema>(
126
124
  node: TreeFieldFromImplicitField<TSchema>,
127
125
  ): TreeFieldFromImplicitField<TSchema>;
126
+
127
+ // TODO: support more clone options
128
+ // /**
129
+ // * Like {@link TreeBeta.create}, except deeply clones existing nodes.
130
+ // * @remarks
131
+ // * This only clones the persisted data associated with a node.
132
+ // * Local state, such as properties added to customized schema classes, will not be cloned:
133
+ // * they will be initialized however they end up after running the constructor, just like if a remote client had inserted the same nodes.
134
+ // */
135
+ // clone<const TSchema extends ImplicitFieldSchema>(
136
+ // original: TreeFieldFromImplicitField<TSchema>,
137
+ // options?: {
138
+ // /**
139
+ // * If set, all identifier's in the cloned tree (See {@link SchemaFactory.identifier}) will be replaced with new ones allocated using the default identifier allocation schema.
140
+ // * Otherwise any identifiers will be preserved as is.
141
+ // */
142
+ // replaceIdentifiers?: true;
143
+ // },
144
+ // ): TreeFieldFromImplicitField<TSchema>;
128
145
  } = {
129
146
  on<K extends keyof TreeChangeEventsBeta<TNode>, TNode extends TreeNode>(
130
147
  node: TNode,
@@ -133,35 +150,18 @@ export const TreeBeta: {
133
150
  ): () => void {
134
151
  return treeNodeApi.on(node, eventName, listener);
135
152
  },
136
- clone<TSchema extends ImplicitFieldSchema>(
153
+ clone<const TSchema extends ImplicitFieldSchema>(
137
154
  node: TreeFieldFromImplicitField<TSchema>,
138
155
  ): Unhydrated<TreeFieldFromImplicitField<TSchema>> {
139
- /* The only non-TreeNode cases are {@link Value} (for an empty optional field) which can be returned as is. */
156
+ /** The only non-TreeNode cases are {@link TreeLeafValue} and `undefined` (for an empty optional field) which can be returned as is. */
140
157
  if (!isTreeNode(node)) {
141
158
  return node;
142
159
  }
143
160
 
144
161
  const kernel = getKernel(node);
145
- /*
146
- * For unhydrated nodes, we can create a cursor by calling `cursorFromInsertable` because the node
147
- * hasn't been inserted yet. We can then create a new node from the cursor.
148
- */
149
- if (!kernel.isHydrated()) {
150
- return createFromCursor(
151
- kernel.schema,
152
- cursorFromInsertable<UnsafeUnknownSchema>(kernel.schema, node),
153
- ) as Unhydrated<TreeFieldFromImplicitField<TSchema>>;
154
- }
155
-
156
- // For hydrated nodes, create a new cursor in the forest and then create a new node from the cursor.
157
- const forest = kernel.context.flexContext.checkout.forest;
158
- const cursor = forest.allocateCursor("tree.clone");
159
- forest.moveCursorToPath(kernel.anchorNode, cursor);
160
- const clonedNode = createFromCursor(
161
- kernel.schema,
162
- cursor as ITreeCursorSynchronous,
163
- ) as Unhydrated<TreeFieldFromImplicitField<TSchema>>;
164
- cursor.free();
165
- return clonedNode;
162
+ const cursor = kernel.getOrCreateInnerNode().borrowCursor();
163
+ return createFromCursor(kernel.schema, cursor) as Unhydrated<
164
+ TreeFieldFromImplicitField<TSchema>
165
+ >;
166
166
  },
167
167
  };
@@ -86,8 +86,7 @@ export type TreeNodeSchemaUnsafe<
86
86
  export interface TreeNodeSchemaClassUnsafe<
87
87
  out Name extends string,
88
88
  out Kind extends NodeKind,
89
- // TODO: maybe this can be more specific (exclude leaves)
90
- out TNode extends Unenforced<TreeNode | TreeLeafValue>,
89
+ out TNode extends Unenforced<TreeNode>,
91
90
  in TInsertable,
92
91
  out ImplicitlyConstructable extends boolean,
93
92
  out Info,
@@ -53,6 +53,7 @@ import { getUnhydratedContext } from "../createContext.js";
53
53
  * @privateRemarks
54
54
  * This can store all possible simple trees,
55
55
  * but it can not store all possible trees representable by our internal representations like FlexTree and JsonableTree.
56
+ * @alpha
56
57
  */
57
58
  export type VerboseTree<THandle = IFluidHandle> =
58
59
  | VerboseTreeNode<THandle>
@@ -82,6 +83,7 @@ export type VerboseTree<THandle = IFluidHandle> =
82
83
  * Unlike `JsonableTree`, leaf nodes are not boxed into node objects, and instead have their schema inferred from the value.
83
84
  * Additionally, sequence fields can only occur on a node that has a single sequence field (with the empty key)
84
85
  * replicating the behavior of simple-tree ArrayNodes.
86
+ * @alpha
85
87
  */
86
88
  export interface VerboseTreeNode<THandle = IFluidHandle> {
87
89
  /**
@@ -109,6 +111,7 @@ export interface VerboseTreeNode<THandle = IFluidHandle> {
109
111
 
110
112
  /**
111
113
  * Options for how to interpret a `VerboseTree<TCustom>` when schema information is available.
114
+ * @alpha
112
115
  */
113
116
  export interface ParseOptions<TCustom> {
114
117
  /**
@@ -816,9 +816,9 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
816
816
  >;
817
817
 
818
818
  public constructor(
819
- input: Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>> | InternalTreeNode,
819
+ input?: Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>> | InternalTreeNode,
820
820
  ) {
821
- super(input);
821
+ super(input ?? []);
822
822
  }
823
823
 
824
824
  #mapTreesFromFieldData(value: Insertable<T>): ExclusiveMapTree[] {
@@ -1077,7 +1077,8 @@ export function arraySchema<
1077
1077
  TreeArrayNode<T> & WithType<TName, NodeKind.Array>,
1078
1078
  Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,
1079
1079
  ImplicitlyConstructable,
1080
- T
1080
+ T,
1081
+ undefined
1081
1082
  >;
1082
1083
 
1083
1084
  const lazyChildTypes = new Lazy(() => normalizeAllowedTypes(info));
@@ -31,7 +31,7 @@ export function getOrCreateNodeFromInnerNode(flexNode: InnerNode): TreeNode | Tr
31
31
  const node = flexNode as unknown as InternalTreeNode;
32
32
  // eslint-disable-next-line unicorn/prefer-ternary
33
33
  if (typeof classSchema === "function") {
34
- return new classSchema(node) as TreeNode;
34
+ return new classSchema(node);
35
35
  } else {
36
36
  return (classSchema as { create(data: FlexTreeNode): TreeValue }).create(flexNode);
37
37
  }
@@ -28,7 +28,9 @@ export type TreeNodeSchema<
28
28
  ImplicitlyConstructable extends boolean = boolean,
29
29
  Info = unknown,
30
30
  > =
31
- | TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>
31
+ | (TNode extends TreeNode
32
+ ? TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>
33
+ : never)
32
34
  | TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>;
33
35
 
34
36
  /**
@@ -39,16 +41,30 @@ export type TreeNodeSchema<
39
41
  * Non-class based schema can have issues with recursive types due to https://github.com/microsoft/TypeScript/issues/55832.
40
42
  * @system @sealed @public
41
43
  */
42
- export interface TreeNodeSchemaNonClass<
43
- out Name extends string = string,
44
- out Kind extends NodeKind = NodeKind,
45
- out TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue,
46
- in TInsertable = never,
47
- out ImplicitlyConstructable extends boolean = boolean,
48
- out Info = unknown,
49
- > extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {
50
- create(data: TInsertable): TNode;
51
- }
44
+ export type TreeNodeSchemaNonClass<
45
+ Name extends string = string,
46
+ Kind extends NodeKind = NodeKind,
47
+ TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue,
48
+ TInsertable = never,
49
+ ImplicitlyConstructable extends boolean = boolean,
50
+ Info = unknown,
51
+ TConstructorExtra = never,
52
+ > = TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info, TInsertable> &
53
+ (undefined extends TConstructorExtra
54
+ ? {
55
+ /**
56
+ * Constructs an {@link Unhydrated} node with this schema.
57
+ * @sealed
58
+ */
59
+ create(data?: TInsertable | TConstructorExtra): TNode;
60
+ }
61
+ : {
62
+ /**
63
+ * Constructs an {@link Unhydrated} node with this schema.
64
+ * @sealed
65
+ */
66
+ create(data: TInsertable | TConstructorExtra): TNode;
67
+ });
52
68
 
53
69
  /**
54
70
  * Tree node schema which is implemented using a class.
@@ -95,24 +111,40 @@ export interface TreeNodeSchemaNonClass<
95
111
  * ```
96
112
  * @sealed @public
97
113
  */
98
- export interface TreeNodeSchemaClass<
99
- out Name extends string = string,
100
- out Kind extends NodeKind = NodeKind,
101
- // TODO: maybe this can be more specific (exclude leaves)
102
- out TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue,
103
- in TInsertable = never,
104
- out ImplicitlyConstructable extends boolean = boolean,
105
- out Info = unknown,
106
- > extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {
107
- /**
108
- * Constructs an {@link Unhydrated} node with this schema.
109
- * @remarks
110
- * This constructor is also used internally to construct hydrated nodes with a different parameter type.
111
- * Therefore, overriding this constructor with different argument types is not type-safe and is not supported.
112
- * @sealed
113
- */
114
- new (data: TInsertable | InternalTreeNode): Unhydrated<TNode>;
115
- }
114
+ export type TreeNodeSchemaClass<
115
+ Name extends string = string,
116
+ Kind extends NodeKind = NodeKind,
117
+ TNode extends TreeNode = TreeNode,
118
+ TInsertable = never,
119
+ ImplicitlyConstructable extends boolean = boolean,
120
+ Info = unknown,
121
+ TConstructorExtra = never,
122
+ > = TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info, TInsertable> &
123
+ (undefined extends TConstructorExtra
124
+ ? {
125
+ /**
126
+ * Constructs an {@link Unhydrated} node with this schema.
127
+ * @remarks
128
+ * This constructor is also used internally to construct hydrated nodes with a different parameter type.
129
+ * Therefore, overriding this constructor with different argument types is not type-safe and is not supported.
130
+ * @sealed
131
+ */
132
+ // The approach suggested by the linter here is more concise, but ir break intellisense for the constructor.
133
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
134
+ new (data?: TInsertable | InternalTreeNode | TConstructorExtra): Unhydrated<TNode>;
135
+ }
136
+ : {
137
+ /**
138
+ * Constructs an {@link Unhydrated} node with this schema.
139
+ * @remarks
140
+ * This constructor is also used internally to construct hydrated nodes with a different parameter type.
141
+ * Therefore, overriding this constructor with different argument types is not type-safe and is not supported.
142
+ * @sealed
143
+ */
144
+ // The approach suggested by the linter here is more concise, but ir break intellisense for the constructor.
145
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
146
+ new (data: TInsertable | InternalTreeNode | TConstructorExtra): Unhydrated<TNode>;
147
+ });
116
148
 
117
149
  /**
118
150
  * Internal helper for utilities that return schema which can be used in class and non class formats depending on the API exposing it.
@@ -124,8 +156,25 @@ export type TreeNodeSchemaBoth<
124
156
  TInsertable = never,
125
157
  ImplicitlyConstructable extends boolean = boolean,
126
158
  Info = unknown,
127
- > = TreeNodeSchemaClass<Name, Kind, TNode, TInsertable, ImplicitlyConstructable, Info> &
128
- TreeNodeSchemaNonClass<Name, Kind, TNode, TInsertable, ImplicitlyConstructable, Info>;
159
+ TConstructorExtra = never,
160
+ > = TreeNodeSchemaClass<
161
+ Name,
162
+ Kind,
163
+ TNode,
164
+ TInsertable,
165
+ ImplicitlyConstructable,
166
+ Info,
167
+ TConstructorExtra
168
+ > &
169
+ TreeNodeSchemaNonClass<
170
+ Name,
171
+ Kind,
172
+ TNode,
173
+ TInsertable,
174
+ ImplicitlyConstructable,
175
+ Info,
176
+ TConstructorExtra
177
+ >;
129
178
 
130
179
  /**
131
180
  * Data common to all tree node schema.
@@ -138,6 +187,7 @@ export interface TreeNodeSchemaCore<
138
187
  out Kind extends NodeKind,
139
188
  out ImplicitlyConstructable extends boolean,
140
189
  out Info = unknown,
190
+ out TInsertable = never,
141
191
  > {
142
192
  /**
143
193
  * Unique (within a document's schema) identifier used to associate nodes with their schema.
@@ -193,6 +243,24 @@ export interface TreeNodeSchemaCore<
193
243
  * @system
194
244
  */
195
245
  readonly childTypes: ReadonlySet<TreeNodeSchema>;
246
+
247
+ /**
248
+ * Constructs an instance of this node type.
249
+ * @remarks
250
+ * Due to TypeScript limitations, the return type of this method can not be very specific.
251
+ * For {@link TreeNodeSchemaClass} prefer using the constructor directly for better typing.
252
+ * For {@link TreeNodeSchemaNonClass} use `create`.
253
+ *
254
+ * @privateRemarks
255
+ * This method signature provides a way to infer `TInsertable` without relying on the constructor, and to construct nodes from schema of unknown kind.
256
+ * This makes customizations of the constructor not impact the typing of insertable content, allowing customization of the constructor,
257
+ * as long as doing so only adds additional supported cases.
258
+ *
259
+ * This cannot be required to return `TNode`:
260
+ * doing so breaks sub-classing of schema since they don't overload this method with a more specific return type.
261
+ * @sealed @system
262
+ */
263
+ createFromInsertable(data: TInsertable): Unhydrated<TreeNode | TreeLeafValue>;
196
264
  }
197
265
 
198
266
  /**
@@ -15,6 +15,7 @@ import {
15
15
  type FieldKindIdentifier,
16
16
  type FieldUpPath,
17
17
  forbiddenFieldKindIdentifier,
18
+ type ITreeCursorSynchronous,
18
19
  type MapTree,
19
20
  type SchemaPolicy,
20
21
  type TreeNodeSchemaIdentifier,
@@ -39,6 +40,7 @@ import {
39
40
  type FlexFieldKind,
40
41
  FieldKinds,
41
42
  type SequenceFieldEditBuilder,
43
+ cursorForMapTreeNode,
42
44
  } from "../../feature-libraries/index.js";
43
45
  import type { Context } from "./context.js";
44
46
  import { createEmitter, type Listenable } from "../../events/index.js";
@@ -168,6 +170,10 @@ export class UnhydratedFlexTreeNode implements UnhydratedFlexTreeNode {
168
170
  return this.location;
169
171
  }
170
172
 
173
+ public borrowCursor(): ITreeCursorSynchronous {
174
+ return cursorForMapTreeNode(this.mapTree);
175
+ }
176
+
171
177
  public tryGetField(key: FieldKey): UnhydratedFlexTreeField | undefined {
172
178
  const field = this.mapTree.fields.get(key);
173
179
  // Only return the field if it is not empty, in order to fulfill the contract of `tryGetField`.
@@ -3,7 +3,6 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type { TreeLeafValue } from "../schemaTypes.js";
7
6
  import type { NodeKind, TreeNodeSchemaClass } from "./treeNodeSchema.js";
8
7
  import type { TreeNode } from "./types.js";
9
8
 
@@ -89,12 +88,5 @@ export interface WithType<
89
88
  /**
90
89
  * Type symbol, marking a type in a way to increase type safety via strong type checking.
91
90
  */
92
- get [typeSchemaSymbol](): TreeNodeSchemaClass<
93
- TName,
94
- TKind,
95
- TreeNode | TreeLeafValue,
96
- never,
97
- boolean,
98
- TInfo
99
- >;
91
+ get [typeSchemaSymbol](): TreeNodeSchemaClass<TName, TKind, TreeNode, never, boolean, TInfo>;
100
92
  }
@@ -7,7 +7,7 @@ import { defaultSchemaPolicy } from "../feature-libraries/index.js";
7
7
  import { getOrCreate } from "../util/index.js";
8
8
  import { Context, UnhydratedContext } from "./core/index.js";
9
9
  import { normalizeFieldSchema, type ImplicitFieldSchema } from "./schemaTypes.js";
10
- import { toStoredSchema } from "./toFlexSchema.js";
10
+ import { toStoredSchema } from "./toStoredSchema.js";
11
11
 
12
12
  const contextCache: WeakMap<ImplicitFieldSchema, Context> = new WeakMap();
13
13