@fluidframework/tree 2.41.0 → 2.42.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 (416) hide show
  1. package/.vscode/settings.json +1 -0
  2. package/CHANGELOG.md +33 -0
  3. package/api-report/tree.alpha.api.md +11 -7
  4. package/dist/alpha.d.ts +1 -0
  5. package/dist/codec/codec.d.ts +23 -3
  6. package/dist/codec/codec.d.ts.map +1 -1
  7. package/dist/codec/codec.js.map +1 -1
  8. package/dist/codec/index.d.ts +1 -1
  9. package/dist/codec/index.d.ts.map +1 -1
  10. package/dist/codec/index.js.map +1 -1
  11. package/dist/codec/versioned/codec.d.ts +35 -2
  12. package/dist/codec/versioned/codec.d.ts.map +1 -1
  13. package/dist/codec/versioned/codec.js +38 -3
  14. package/dist/codec/versioned/codec.js.map +1 -1
  15. package/dist/core/tree/detachedFieldIndex.d.ts +2 -2
  16. package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
  17. package/dist/core/tree/detachedFieldIndex.js +5 -1
  18. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  19. package/dist/core/tree/mapTree.d.ts +2 -1
  20. package/dist/core/tree/mapTree.d.ts.map +1 -1
  21. package/dist/core/tree/mapTree.js +11 -5
  22. package/dist/core/tree/mapTree.js.map +1 -1
  23. package/dist/core/tree/visitorUtils.d.ts +2 -2
  24. package/dist/core/tree/visitorUtils.d.ts.map +1 -1
  25. package/dist/core/tree/visitorUtils.js.map +1 -1
  26. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +3 -2
  27. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  28. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  29. package/dist/feature-libraries/default-schema/schemaChecker.d.ts +4 -3
  30. package/dist/feature-libraries/default-schema/schemaChecker.d.ts.map +1 -1
  31. package/dist/feature-libraries/default-schema/schemaChecker.js +4 -3
  32. package/dist/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  33. package/dist/feature-libraries/flex-tree/context.d.ts +14 -6
  34. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  35. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  36. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +34 -14
  37. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  38. package/dist/feature-libraries/flex-tree/flexTreeTypes.js +4 -0
  39. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  40. package/dist/feature-libraries/flex-tree/index.d.ts +2 -2
  41. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  42. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  43. package/dist/feature-libraries/flex-tree/lazyField.d.ts +6 -6
  44. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  45. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  46. package/dist/feature-libraries/flex-tree/lazyNode.d.ts +3 -2
  47. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  48. package/dist/feature-libraries/flex-tree/lazyNode.js +3 -0
  49. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  50. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +2 -2
  51. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  52. package/dist/feature-libraries/forest-summary/forestSummarizer.js +7 -7
  53. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  54. package/dist/feature-libraries/index.d.ts +2 -2
  55. package/dist/feature-libraries/index.d.ts.map +1 -1
  56. package/dist/feature-libraries/index.js +4 -2
  57. package/dist/feature-libraries/index.js.map +1 -1
  58. package/dist/feature-libraries/mapTreeCursor.d.ts +39 -3
  59. package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
  60. package/dist/feature-libraries/mapTreeCursor.js +45 -7
  61. package/dist/feature-libraries/mapTreeCursor.js.map +1 -1
  62. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  63. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  64. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +5 -5
  65. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  66. package/dist/feature-libraries/treeCursorUtils.d.ts +5 -1
  67. package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  68. package/dist/feature-libraries/treeCursorUtils.js +8 -2
  69. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  70. package/dist/index.d.ts +1 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js.map +1 -1
  73. package/dist/packageVersion.d.ts +1 -1
  74. package/dist/packageVersion.js +1 -1
  75. package/dist/packageVersion.js.map +1 -1
  76. package/dist/shared-tree/schematizingTreeView.d.ts +11 -1
  77. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  78. package/dist/shared-tree/schematizingTreeView.js +36 -22
  79. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  80. package/dist/shared-tree/sharedTree.d.ts +3 -3
  81. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  82. package/dist/shared-tree/sharedTree.js +1 -0
  83. package/dist/shared-tree/sharedTree.js.map +1 -1
  84. package/dist/shared-tree/tree.d.ts.map +1 -1
  85. package/dist/shared-tree/tree.js +8 -24
  86. package/dist/shared-tree/tree.js.map +1 -1
  87. package/dist/shared-tree/treeAlpha.d.ts +2 -3
  88. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  89. package/dist/shared-tree/treeAlpha.js +13 -15
  90. package/dist/shared-tree/treeAlpha.js.map +1 -1
  91. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  92. package/dist/shared-tree/treeCheckout.js +5 -2
  93. package/dist/shared-tree/treeCheckout.js.map +1 -1
  94. package/dist/simple-tree/api/configuration.d.ts +2 -2
  95. package/dist/simple-tree/api/configuration.js +1 -1
  96. package/dist/simple-tree/api/configuration.js.map +1 -1
  97. package/dist/simple-tree/api/create.d.ts +9 -4
  98. package/dist/simple-tree/api/create.d.ts.map +1 -1
  99. package/dist/simple-tree/api/create.js +29 -16
  100. package/dist/simple-tree/api/create.js.map +1 -1
  101. package/dist/simple-tree/api/customTree.d.ts +4 -0
  102. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  103. package/dist/simple-tree/api/customTree.js +9 -1
  104. package/dist/simple-tree/api/customTree.js.map +1 -1
  105. package/dist/simple-tree/api/index.d.ts +1 -1
  106. package/dist/simple-tree/api/index.d.ts.map +1 -1
  107. package/dist/simple-tree/api/index.js +1 -2
  108. package/dist/simple-tree/api/index.js.map +1 -1
  109. package/dist/simple-tree/api/schemaFactory.d.ts +10 -2
  110. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  111. package/dist/simple-tree/api/schemaFactory.js +38 -9
  112. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  113. package/dist/simple-tree/api/treeNodeApi.d.ts +14 -3
  114. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  115. package/dist/simple-tree/api/treeNodeApi.js +32 -17
  116. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  117. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  118. package/dist/simple-tree/api/verboseTree.js +12 -9
  119. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  120. package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  121. package/dist/simple-tree/core/getOrCreateNode.js +2 -1
  122. package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
  123. package/dist/simple-tree/core/index.d.ts +2 -2
  124. package/dist/simple-tree/core/index.d.ts.map +1 -1
  125. package/dist/simple-tree/core/index.js +3 -4
  126. package/dist/simple-tree/core/index.js.map +1 -1
  127. package/dist/simple-tree/core/treeNodeKernel.d.ts +15 -25
  128. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  129. package/dist/simple-tree/core/treeNodeKernel.js +26 -33
  130. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  131. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +128 -59
  132. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  133. package/dist/simple-tree/core/unhydratedFlexTree.js +169 -182
  134. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  135. package/dist/simple-tree/index.d.ts +3 -3
  136. package/dist/simple-tree/index.d.ts.map +1 -1
  137. package/dist/simple-tree/index.js +5 -5
  138. package/dist/simple-tree/index.js.map +1 -1
  139. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  140. package/dist/simple-tree/node-kinds/array/arrayNode.js +5 -6
  141. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  142. package/dist/simple-tree/node-kinds/index.d.ts +1 -1
  143. package/dist/simple-tree/node-kinds/index.d.ts.map +1 -1
  144. package/dist/simple-tree/node-kinds/index.js +1 -2
  145. package/dist/simple-tree/node-kinds/index.js.map +1 -1
  146. package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  147. package/dist/simple-tree/node-kinds/map/mapNode.js +2 -2
  148. package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  149. package/dist/simple-tree/node-kinds/object/index.d.ts +1 -1
  150. package/dist/simple-tree/node-kinds/object/index.d.ts.map +1 -1
  151. package/dist/simple-tree/node-kinds/object/index.js +1 -2
  152. package/dist/simple-tree/node-kinds/object/index.js.map +1 -1
  153. package/dist/simple-tree/node-kinds/object/objectNode.d.ts +3 -14
  154. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  155. package/dist/simple-tree/node-kinds/object/objectNode.js +12 -43
  156. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  157. package/dist/simple-tree/prepareForInsertion.d.ts +20 -6
  158. package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
  159. package/dist/simple-tree/prepareForInsertion.js +26 -19
  160. package/dist/simple-tree/prepareForInsertion.js.map +1 -1
  161. package/dist/simple-tree/schemaTypes.d.ts +8 -8
  162. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  163. package/dist/simple-tree/schemaTypes.js.map +1 -1
  164. package/dist/simple-tree/toStoredSchema.d.ts +6 -1
  165. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  166. package/dist/simple-tree/toStoredSchema.js +6 -3
  167. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  168. package/dist/simple-tree/{toMapTree.d.ts → unhydratedFlexTreeFromInsertable.d.ts} +12 -23
  169. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -0
  170. package/dist/simple-tree/{toMapTree.js → unhydratedFlexTreeFromInsertable.js} +103 -185
  171. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -0
  172. package/dist/treeFactory.d.ts.map +1 -1
  173. package/dist/treeFactory.js +6 -1
  174. package/dist/treeFactory.js.map +1 -1
  175. package/dist/util/index.d.ts +1 -1
  176. package/dist/util/index.d.ts.map +1 -1
  177. package/dist/util/index.js +2 -1
  178. package/dist/util/index.js.map +1 -1
  179. package/dist/util/utils.d.ts +4 -0
  180. package/dist/util/utils.d.ts.map +1 -1
  181. package/dist/util/utils.js +8 -1
  182. package/dist/util/utils.js.map +1 -1
  183. package/docs/user-facing/schema-evolution.md +1 -1
  184. package/lib/alpha.d.ts +1 -0
  185. package/lib/codec/codec.d.ts +23 -3
  186. package/lib/codec/codec.d.ts.map +1 -1
  187. package/lib/codec/codec.js.map +1 -1
  188. package/lib/codec/index.d.ts +1 -1
  189. package/lib/codec/index.d.ts.map +1 -1
  190. package/lib/codec/index.js.map +1 -1
  191. package/lib/codec/versioned/codec.d.ts +35 -2
  192. package/lib/codec/versioned/codec.d.ts.map +1 -1
  193. package/lib/codec/versioned/codec.js +36 -2
  194. package/lib/codec/versioned/codec.js.map +1 -1
  195. package/lib/core/tree/detachedFieldIndex.d.ts +2 -2
  196. package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
  197. package/lib/core/tree/detachedFieldIndex.js +6 -2
  198. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  199. package/lib/core/tree/mapTree.d.ts +2 -1
  200. package/lib/core/tree/mapTree.d.ts.map +1 -1
  201. package/lib/core/tree/mapTree.js +11 -5
  202. package/lib/core/tree/mapTree.js.map +1 -1
  203. package/lib/core/tree/visitorUtils.d.ts +2 -2
  204. package/lib/core/tree/visitorUtils.d.ts.map +1 -1
  205. package/lib/core/tree/visitorUtils.js.map +1 -1
  206. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +3 -2
  207. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  208. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  209. package/lib/feature-libraries/default-schema/schemaChecker.d.ts +4 -3
  210. package/lib/feature-libraries/default-schema/schemaChecker.d.ts.map +1 -1
  211. package/lib/feature-libraries/default-schema/schemaChecker.js +4 -3
  212. package/lib/feature-libraries/default-schema/schemaChecker.js.map +1 -1
  213. package/lib/feature-libraries/flex-tree/context.d.ts +14 -6
  214. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  215. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  216. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +34 -14
  217. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  218. package/lib/feature-libraries/flex-tree/flexTreeTypes.js +4 -0
  219. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  220. package/lib/feature-libraries/flex-tree/index.d.ts +2 -2
  221. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  222. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  223. package/lib/feature-libraries/flex-tree/lazyField.d.ts +6 -6
  224. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  225. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  226. package/lib/feature-libraries/flex-tree/lazyNode.d.ts +3 -2
  227. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  228. package/lib/feature-libraries/flex-tree/lazyNode.js +3 -0
  229. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  230. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +2 -2
  231. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  232. package/lib/feature-libraries/forest-summary/forestSummarizer.js +2 -2
  233. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  234. package/lib/feature-libraries/index.d.ts +2 -2
  235. package/lib/feature-libraries/index.d.ts.map +1 -1
  236. package/lib/feature-libraries/index.js +1 -1
  237. package/lib/feature-libraries/index.js.map +1 -1
  238. package/lib/feature-libraries/mapTreeCursor.d.ts +39 -3
  239. package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
  240. package/lib/feature-libraries/mapTreeCursor.js +43 -7
  241. package/lib/feature-libraries/mapTreeCursor.js.map +1 -1
  242. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  243. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  244. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +5 -5
  245. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  246. package/lib/feature-libraries/treeCursorUtils.d.ts +5 -1
  247. package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  248. package/lib/feature-libraries/treeCursorUtils.js +8 -2
  249. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  250. package/lib/index.d.ts +1 -1
  251. package/lib/index.d.ts.map +1 -1
  252. package/lib/index.js.map +1 -1
  253. package/lib/packageVersion.d.ts +1 -1
  254. package/lib/packageVersion.js +1 -1
  255. package/lib/packageVersion.js.map +1 -1
  256. package/lib/shared-tree/schematizingTreeView.d.ts +11 -1
  257. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  258. package/lib/shared-tree/schematizingTreeView.js +34 -21
  259. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  260. package/lib/shared-tree/sharedTree.d.ts +3 -3
  261. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  262. package/lib/shared-tree/sharedTree.js +2 -1
  263. package/lib/shared-tree/sharedTree.js.map +1 -1
  264. package/lib/shared-tree/tree.d.ts.map +1 -1
  265. package/lib/shared-tree/tree.js +2 -18
  266. package/lib/shared-tree/tree.js.map +1 -1
  267. package/lib/shared-tree/treeAlpha.d.ts +2 -3
  268. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  269. package/lib/shared-tree/treeAlpha.js +4 -6
  270. package/lib/shared-tree/treeAlpha.js.map +1 -1
  271. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  272. package/lib/shared-tree/treeCheckout.js +6 -3
  273. package/lib/shared-tree/treeCheckout.js.map +1 -1
  274. package/lib/simple-tree/api/configuration.d.ts +2 -2
  275. package/lib/simple-tree/api/configuration.js +1 -1
  276. package/lib/simple-tree/api/configuration.js.map +1 -1
  277. package/lib/simple-tree/api/create.d.ts +9 -4
  278. package/lib/simple-tree/api/create.d.ts.map +1 -1
  279. package/lib/simple-tree/api/create.js +22 -9
  280. package/lib/simple-tree/api/create.js.map +1 -1
  281. package/lib/simple-tree/api/customTree.d.ts +4 -0
  282. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  283. package/lib/simple-tree/api/customTree.js +7 -0
  284. package/lib/simple-tree/api/customTree.js.map +1 -1
  285. package/lib/simple-tree/api/index.d.ts +1 -1
  286. package/lib/simple-tree/api/index.d.ts.map +1 -1
  287. package/lib/simple-tree/api/index.js +1 -1
  288. package/lib/simple-tree/api/index.js.map +1 -1
  289. package/lib/simple-tree/api/schemaFactory.d.ts +10 -2
  290. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  291. package/lib/simple-tree/api/schemaFactory.js +40 -11
  292. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  293. package/lib/simple-tree/api/treeNodeApi.d.ts +14 -3
  294. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  295. package/lib/simple-tree/api/treeNodeApi.js +35 -20
  296. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  297. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  298. package/lib/simple-tree/api/verboseTree.js +13 -10
  299. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  300. package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  301. package/lib/simple-tree/core/getOrCreateNode.js +3 -2
  302. package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
  303. package/lib/simple-tree/core/index.d.ts +2 -2
  304. package/lib/simple-tree/core/index.d.ts.map +1 -1
  305. package/lib/simple-tree/core/index.js +2 -2
  306. package/lib/simple-tree/core/index.js.map +1 -1
  307. package/lib/simple-tree/core/treeNodeKernel.d.ts +15 -25
  308. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  309. package/lib/simple-tree/core/treeNodeKernel.js +24 -32
  310. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  311. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +128 -59
  312. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  313. package/lib/simple-tree/core/unhydratedFlexTree.js +166 -181
  314. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  315. package/lib/simple-tree/index.d.ts +3 -3
  316. package/lib/simple-tree/index.d.ts.map +1 -1
  317. package/lib/simple-tree/index.js +3 -3
  318. package/lib/simple-tree/index.js.map +1 -1
  319. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  320. package/lib/simple-tree/node-kinds/array/arrayNode.js +4 -5
  321. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  322. package/lib/simple-tree/node-kinds/index.d.ts +1 -1
  323. package/lib/simple-tree/node-kinds/index.d.ts.map +1 -1
  324. package/lib/simple-tree/node-kinds/index.js +1 -1
  325. package/lib/simple-tree/node-kinds/index.js.map +1 -1
  326. package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  327. package/lib/simple-tree/node-kinds/map/mapNode.js +3 -3
  328. package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  329. package/lib/simple-tree/node-kinds/object/index.d.ts +1 -1
  330. package/lib/simple-tree/node-kinds/object/index.d.ts.map +1 -1
  331. package/lib/simple-tree/node-kinds/object/index.js +1 -1
  332. package/lib/simple-tree/node-kinds/object/index.js.map +1 -1
  333. package/lib/simple-tree/node-kinds/object/objectNode.d.ts +3 -14
  334. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  335. package/lib/simple-tree/node-kinds/object/objectNode.js +3 -33
  336. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  337. package/lib/simple-tree/prepareForInsertion.d.ts +20 -6
  338. package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
  339. package/lib/simple-tree/prepareForInsertion.js +25 -19
  340. package/lib/simple-tree/prepareForInsertion.js.map +1 -1
  341. package/lib/simple-tree/schemaTypes.d.ts +8 -8
  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/toStoredSchema.d.ts +6 -1
  345. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  346. package/lib/simple-tree/toStoredSchema.js +4 -1
  347. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  348. package/lib/simple-tree/{toMapTree.d.ts → unhydratedFlexTreeFromInsertable.d.ts} +12 -23
  349. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -0
  350. package/lib/simple-tree/{toMapTree.js → unhydratedFlexTreeFromInsertable.js} +105 -186
  351. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -0
  352. package/lib/treeFactory.d.ts.map +1 -1
  353. package/lib/treeFactory.js +6 -1
  354. package/lib/treeFactory.js.map +1 -1
  355. package/lib/util/index.d.ts +1 -1
  356. package/lib/util/index.d.ts.map +1 -1
  357. package/lib/util/index.js +1 -1
  358. package/lib/util/index.js.map +1 -1
  359. package/lib/util/utils.d.ts +4 -0
  360. package/lib/util/utils.d.ts.map +1 -1
  361. package/lib/util/utils.js +6 -0
  362. package/lib/util/utils.js.map +1 -1
  363. package/package.json +21 -21
  364. package/src/codec/codec.ts +24 -3
  365. package/src/codec/index.ts +1 -0
  366. package/src/codec/versioned/codec.ts +42 -5
  367. package/src/core/tree/detachedFieldIndex.ts +13 -4
  368. package/src/core/tree/mapTree.ts +22 -7
  369. package/src/core/tree/visitorUtils.ts +2 -2
  370. package/src/feature-libraries/default-schema/defaultEditBuilder.ts +3 -2
  371. package/src/feature-libraries/default-schema/schemaChecker.ts +7 -6
  372. package/src/feature-libraries/flex-tree/context.ts +17 -7
  373. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +36 -15
  374. package/src/feature-libraries/flex-tree/index.ts +4 -0
  375. package/src/feature-libraries/flex-tree/lazyField.ts +8 -6
  376. package/src/feature-libraries/flex-tree/lazyNode.ts +6 -2
  377. package/src/feature-libraries/forest-summary/forestSummarizer.ts +3 -2
  378. package/src/feature-libraries/index.ts +9 -0
  379. package/src/feature-libraries/mapTreeCursor.ts +103 -16
  380. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +9 -5
  381. package/src/feature-libraries/treeCursorUtils.ts +21 -10
  382. package/src/index.ts +1 -0
  383. package/src/packageVersion.ts +1 -1
  384. package/src/shared-tree/schematizingTreeView.ts +40 -22
  385. package/src/shared-tree/sharedTree.ts +9 -3
  386. package/src/shared-tree/tree.ts +5 -20
  387. package/src/shared-tree/treeAlpha.ts +17 -11
  388. package/src/shared-tree/treeCheckout.ts +6 -3
  389. package/src/simple-tree/api/configuration.ts +3 -3
  390. package/src/simple-tree/api/create.ts +49 -19
  391. package/src/simple-tree/api/customTree.ts +10 -0
  392. package/src/simple-tree/api/index.ts +1 -4
  393. package/src/simple-tree/api/schemaFactory.ts +62 -13
  394. package/src/simple-tree/api/treeNodeApi.ts +48 -27
  395. package/src/simple-tree/api/verboseTree.ts +15 -12
  396. package/src/simple-tree/core/getOrCreateNode.ts +4 -2
  397. package/src/simple-tree/core/index.ts +2 -3
  398. package/src/simple-tree/core/treeNodeKernel.ts +37 -54
  399. package/src/simple-tree/core/unhydratedFlexTree.ts +222 -261
  400. package/src/simple-tree/index.ts +3 -3
  401. package/src/simple-tree/node-kinds/array/arrayNode.ts +12 -13
  402. package/src/simple-tree/node-kinds/index.ts +0 -1
  403. package/src/simple-tree/node-kinds/map/mapNode.ts +6 -9
  404. package/src/simple-tree/node-kinds/object/index.ts +0 -1
  405. package/src/simple-tree/node-kinds/object/objectNode.ts +7 -49
  406. package/src/simple-tree/prepareForInsertion.ts +49 -42
  407. package/src/simple-tree/schemaTypes.ts +9 -8
  408. package/src/simple-tree/toStoredSchema.ts +7 -1
  409. package/src/simple-tree/{toMapTree.ts → unhydratedFlexTreeFromInsertable.ts} +134 -226
  410. package/src/treeFactory.ts +6 -1
  411. package/src/util/index.ts +1 -0
  412. package/src/util/utils.ts +7 -0
  413. package/dist/simple-tree/toMapTree.d.ts.map +0 -1
  414. package/dist/simple-tree/toMapTree.js.map +0 -1
  415. package/lib/simple-tree/toMapTree.d.ts.map +0 -1
  416. package/lib/simple-tree/toMapTree.js.map +0 -1
@@ -7,7 +7,6 @@ import { unreachableCase, fail } from "@fluidframework/core-utils/internal";
7
7
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
8
8
 
9
9
  import {
10
- type MapTree,
11
10
  type TreeFieldStoredSchema,
12
11
  LeafNodeStoredSchema,
13
12
  ObjectNodeStoredSchema,
@@ -16,6 +15,8 @@ import {
16
15
  type SchemaAndPolicy,
17
16
  } from "../../core/index.js";
18
17
  import { allowsValue } from "../valueUtilities.js";
18
+ import type { MapTreeFieldViewGeneric, MinimalMapTreeNodeView } from "../mapTreeCursor.js";
19
+ import { iterableHasSome, mapIterable } from "../../util/index.js";
19
20
 
20
21
  export enum SchemaValidationError {
21
22
  Field_KindNotInSchemaPolicy,
@@ -45,7 +46,7 @@ export function inSchemaOrThrow(maybeError: SchemaValidationError | undefined):
45
46
  * Deeply checks that the provided node complies with the schema based on its identifier.
46
47
  */
47
48
  export function isNodeInSchema(
48
- node: MapTree,
49
+ node: MinimalMapTreeNodeView,
49
50
  schemaAndPolicy: SchemaAndPolicy,
50
51
  ): SchemaValidationError | undefined {
51
52
  // Validate the schema declared by the node exists
@@ -57,7 +58,7 @@ export function isNodeInSchema(
57
58
  // Validate the node is well formed according to its schema
58
59
 
59
60
  if (schema instanceof LeafNodeStoredSchema) {
60
- if (node.fields.size !== 0) {
61
+ if (iterableHasSome(node.fields)) {
61
62
  return SchemaValidationError.LeafNode_FieldsNotAllowed;
62
63
  }
63
64
  if (!allowsValue(schema.leafValue, node.value)) {
@@ -69,7 +70,7 @@ export function isNodeInSchema(
69
70
  }
70
71
 
71
72
  if (schema instanceof ObjectNodeStoredSchema) {
72
- const uncheckedFieldsFromNode = new Set(node.fields.keys());
73
+ const uncheckedFieldsFromNode = new Set(mapIterable(node.fields, ([key, field]) => key));
73
74
  for (const [fieldKey, fieldSchema] of schema.objectNodeFields) {
74
75
  const nodeField = node.fields.get(fieldKey) ?? [];
75
76
  const fieldInSchemaResult = isFieldInSchema(nodeField, fieldSchema, schemaAndPolicy);
@@ -86,7 +87,7 @@ export function isNodeInSchema(
86
87
  return SchemaValidationError.ObjectNode_FieldNotInSchema;
87
88
  }
88
89
  } else if (schema instanceof MapNodeStoredSchema) {
89
- for (const field of node.fields.values()) {
90
+ for (const [_key, field] of node.fields) {
90
91
  const fieldInSchemaResult = isFieldInSchema(field, schema.mapFields, schemaAndPolicy);
91
92
  if (fieldInSchemaResult !== undefined) {
92
93
  return fieldInSchemaResult;
@@ -104,7 +105,7 @@ export function isNodeInSchema(
104
105
  * Deeply checks that the nodes comply with the field schema and included schema.
105
106
  */
106
107
  export function isFieldInSchema(
107
- childNodes: readonly MapTree[],
108
+ childNodes: MapTreeFieldViewGeneric<MinimalMapTreeNodeView>,
108
109
  schema: TreeFieldStoredSchema,
109
110
  schemaAndPolicy: SchemaAndPolicy,
110
111
  ): SchemaValidationError | undefined {
@@ -54,16 +54,12 @@ export interface FlexTreeContext {
54
54
  }
55
55
 
56
56
  /**
57
- * A common context of a "forest" of FlexTrees.
58
- * It handles group operations like transforming cursors into anchors for edits.
57
+ * Subset of a hydrated context which can be used in more cases (like before the root and events are set up).
59
58
  */
60
- export interface FlexTreeHydratedContext extends FlexTreeContext {
61
- readonly events: Listenable<ForestEvents>;
59
+ export interface FlexTreeHydratedContextMinimal {
62
60
  /**
63
- * Gets the root field of the tree.
61
+ * The {@link NodeIdentifierManager} responsible for allocating and compressing identifiers for nodes in this context.
64
62
  */
65
- get root(): FlexTreeField;
66
-
67
63
  readonly nodeKeyManager: NodeIdentifierManager;
68
64
 
69
65
  /**
@@ -72,6 +68,20 @@ export interface FlexTreeHydratedContext extends FlexTreeContext {
72
68
  readonly checkout: ITreeCheckout;
73
69
  }
74
70
 
71
+ /**
72
+ * A common context of a "forest" of FlexTrees.
73
+ * It handles group operations like transforming cursors into anchors for edits.
74
+ */
75
+ export interface FlexTreeHydratedContext
76
+ extends FlexTreeContext,
77
+ FlexTreeHydratedContextMinimal {
78
+ readonly events: Listenable<ForestEvents>;
79
+ /**
80
+ * Gets the root field of the tree.
81
+ */
82
+ get root(): FlexTreeField;
83
+ }
84
+
75
85
  /**
76
86
  * Creating multiple flex tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.
77
87
  * This slot is used to detect if one already exists and error if creating a second.
@@ -5,7 +5,6 @@
5
5
 
6
6
  import {
7
7
  type AnchorNode,
8
- type ExclusiveMapTree,
9
8
  type FieldKey,
10
9
  type FieldKindIdentifier,
11
10
  type ITreeCursorSynchronous,
@@ -20,15 +19,16 @@ import type {
20
19
  ValueFieldEditBuilder,
21
20
  OptionalFieldEditBuilder,
22
21
  } from "../default-schema/index.js";
22
+ import type { MinimalMapTreeNodeView } from "../mapTreeCursor.js";
23
23
  import type { FlexFieldKind } from "../modular-schema/index.js";
24
24
 
25
- import type { FlexTreeContext } from "./context.js";
25
+ import type { FlexTreeContext, FlexTreeHydratedContext } from "./context.js";
26
26
 
27
27
  /**
28
28
  * An anchor slot which records the {@link FlexTreeNode} associated with that anchor, if there is one.
29
29
  * @remarks This always points to a "real" {@link FlexTreeNode} (i.e. a `LazyTreeNode`), never to a "raw" node.
30
30
  */
31
- export const flexTreeSlot = anchorSlot<FlexTreeNode>();
31
+ export const flexTreeSlot = anchorSlot<HydratedFlexTreeNode>();
32
32
 
33
33
  /**
34
34
  * Indicates that an object is a flex tree.
@@ -98,6 +98,10 @@ export enum TreeStatus {
98
98
  * Nodes can enter this state for multiple reasons:
99
99
  * - The node was removed and nothing (e.g. undo/redo history) kept it from being cleaned up.
100
100
  * - The {@link TreeView} was disposed or had a schema change which made the tree incompatible.
101
+ *
102
+ * Deleted nodes' contents should not be observed or edited. This includes functionality exposed via {@link (Tree:variable)},
103
+ * with the exception of {@link TreeNodeApi.status}.
104
+ *
101
105
  * @privateRemarks
102
106
  * There was planned work (AB#17948) to make the first reason a node could become "Deleted" impossible,
103
107
  * at least as an opt in feature,
@@ -169,16 +173,6 @@ export interface FlexTreeNode extends FlexTreeEntity {
169
173
 
170
174
  boxedIterator(): IterableIterator<FlexTreeField>;
171
175
 
172
- /**
173
- * The anchor node associated with this node
174
- *
175
- * @remarks
176
- * The ref count keeping this alive is owned by the FlexTreeNode:
177
- * if holding onto this anchor for longer than the FlexTreeNode might be alive,
178
- * a separate Anchor (and thus ref count) must be allocated to keep it alive.
179
- */
180
- readonly anchorNode: AnchorNode;
181
-
182
176
  /**
183
177
  * Returns an iterable of keys for non-empty fields.
184
178
  *
@@ -202,6 +196,33 @@ export interface FlexTreeNode extends FlexTreeEntity {
202
196
  * Must not be held onto across edits or any other tree API use.
203
197
  */
204
198
  borrowCursor(): ITreeCursorSynchronous;
199
+
200
+ /**
201
+ * If true, this node is a {@link HydratedFlexTreeNode}.
202
+ *
203
+ * If false, this node is unhydrated.
204
+ */
205
+ isHydrated(): this is HydratedFlexTreeNode;
206
+ }
207
+
208
+ /**
209
+ * A FlexTreeNode that is hydrated, meaning it is associated with a {@link FlexTreeHydratedContext}.
210
+ */
211
+ export interface HydratedFlexTreeNode extends FlexTreeNode {
212
+ /**
213
+ * {@inheritDoc FlexTreeNode.context}
214
+ */
215
+ readonly context: FlexTreeHydratedContext;
216
+
217
+ /**
218
+ * The anchor node associated with this node
219
+ *
220
+ * @remarks
221
+ * The ref count keeping this alive is owned by the FlexTreeNode:
222
+ * if holding onto this anchor for longer than the FlexTreeNode might be alive,
223
+ * a separate Anchor (and thus ref count) must be allocated to keep it alive.
224
+ */
225
+ readonly anchorNode: AnchorNode;
205
226
  }
206
227
 
207
228
  /**
@@ -278,12 +299,12 @@ export interface FlexTreeField extends FlexTreeEntity {
278
299
  /**
279
300
  * Typed tree for inserting as the content of a field.
280
301
  */
281
- export type FlexibleFieldContent = ExclusiveMapTree[];
302
+ export type FlexibleFieldContent = readonly FlexibleNodeContent[];
282
303
 
283
304
  /**
284
305
  * Tree for inserting as a node.
285
306
  */
286
- export type FlexibleNodeContent = ExclusiveMapTree;
307
+ export type FlexibleNodeContent = MinimalMapTreeNodeView;
287
308
 
288
309
  /**
289
310
  * {@link FlexTreeField} that stores a sequence of children.
@@ -17,6 +17,9 @@ export {
17
17
  FlexTreeEntityKind,
18
18
  isFlexTreeNode,
19
19
  flexTreeSlot,
20
+ type FlexibleNodeContent,
21
+ type FlexibleFieldContent,
22
+ type HydratedFlexTreeNode,
20
23
  } from "./flexTreeTypes.js";
21
24
 
22
25
  export {
@@ -32,6 +35,7 @@ export {
32
35
  type FlexTreeHydratedContext,
33
36
  Context,
34
37
  ContextSlot,
38
+ type FlexTreeHydratedContextMinimal,
35
39
  } from "./context.js";
36
40
 
37
41
  export { type FlexTreeNodeEvents } from "./treeEvents.js";
@@ -37,12 +37,14 @@ import type { Context } from "./context.js";
37
37
  import {
38
38
  FlexTreeEntityKind,
39
39
  type FlexTreeField,
40
- type FlexTreeNode,
41
40
  type FlexTreeOptionalField,
42
41
  type FlexTreeRequiredField,
43
42
  type FlexTreeSequenceField,
44
43
  type FlexTreeTypedField,
45
44
  type FlexTreeUnknownUnboxed,
45
+ type FlexibleFieldContent,
46
+ type FlexibleNodeContent,
47
+ type HydratedFlexTreeNode,
46
48
  TreeStatus,
47
49
  flexTreeMarker,
48
50
  flexTreeSlot,
@@ -159,7 +161,7 @@ export abstract class LazyField extends LazyEntity<FieldAnchor> implements FlexT
159
161
  return this.schema === kind.identifier;
160
162
  }
161
163
 
162
- public get parent(): FlexTreeNode | undefined {
164
+ public get parent(): HydratedFlexTreeNode | undefined {
163
165
  if (this.anchor.parent === undefined) {
164
166
  return undefined;
165
167
  }
@@ -193,7 +195,7 @@ export abstract class LazyField extends LazyEntity<FieldAnchor> implements FlexT
193
195
  );
194
196
  }
195
197
 
196
- public boxedAt(index: number): FlexTreeNode | undefined {
198
+ public boxedAt(index: number): HydratedFlexTreeNode | undefined {
197
199
  const finalIndex = indexForAt(index, this.length);
198
200
 
199
201
  if (finalIndex === undefined) {
@@ -207,7 +209,7 @@ export abstract class LazyField extends LazyEntity<FieldAnchor> implements FlexT
207
209
  return Array.from(this, callbackfn);
208
210
  }
209
211
 
210
- public boxedIterator(): IterableIterator<FlexTreeNode> {
212
+ public boxedIterator(): IterableIterator<HydratedFlexTreeNode> {
211
213
  return iterateCursorField(this.cursor, (cursor) => makeTree(this.context, cursor));
212
214
  }
213
215
 
@@ -263,7 +265,7 @@ export class LazySequence extends LazyField implements FlexTreeSequenceField {
263
265
  return this.map((x) => x);
264
266
  }
265
267
 
266
- public editor: SequenceFieldEditBuilder<ExclusiveMapTree[]> = {
268
+ public editor: SequenceFieldEditBuilder<FlexibleFieldContent> = {
267
269
  insert: (index, newContent) => {
268
270
  this.sequenceEditor().insert(index, cursorForMapTreeField(newContent));
269
271
  },
@@ -279,7 +281,7 @@ export class LazySequence extends LazyField implements FlexTreeSequenceField {
279
281
  }
280
282
 
281
283
  export class LazyValueField extends LazyField implements FlexTreeRequiredField {
282
- public editor: ValueFieldEditBuilder<ExclusiveMapTree> = {
284
+ public editor: ValueFieldEditBuilder<FlexibleNodeContent> = {
283
285
  set: (newContent) => {
284
286
  this.valueFieldEditor().set(cursorForMapTreeField([newContent]));
285
287
  },
@@ -28,7 +28,7 @@ import type { Context } from "./context.js";
28
28
  import {
29
29
  FlexTreeEntityKind,
30
30
  type FlexTreeField,
31
- type FlexTreeNode,
31
+ type HydratedFlexTreeNode,
32
32
  flexTreeMarker,
33
33
  flexTreeSlot,
34
34
  } from "./flexTreeTypes.js";
@@ -63,7 +63,7 @@ function cleanupTree(anchor: AnchorNode): void {
63
63
  /**
64
64
  * Lazy implementation of {@link FlexTreeNode}.
65
65
  */
66
- export class LazyTreeNode extends LazyEntity<Anchor> implements FlexTreeNode {
66
+ export class LazyTreeNode extends LazyEntity<Anchor> implements HydratedFlexTreeNode {
67
67
  public get [flexTreeMarker](): FlexTreeEntityKind.Node {
68
68
  return FlexTreeEntityKind.Node;
69
69
  }
@@ -88,6 +88,10 @@ export class LazyTreeNode extends LazyEntity<Anchor> implements FlexTreeNode {
88
88
  this.#removeDeleteCallback = anchorNode.events.on("afterDestroy", cleanupTree);
89
89
  }
90
90
 
91
+ public isHydrated(): this is HydratedFlexTreeNode {
92
+ return true;
93
+ }
94
+
91
95
  public borrowCursor(): ITreeCursorSynchronous {
92
96
  return this.cursor as ITreeCursorSynchronous;
93
97
  }
@@ -13,7 +13,7 @@ import type {
13
13
  } from "@fluidframework/runtime-definitions/internal";
14
14
  import { createSingleBlobSummary } from "@fluidframework/shared-object-base/internal";
15
15
 
16
- import { type ICodecOptions, noopValidator } from "../../codec/index.js";
16
+ import type { CodecWriteOptions } from "../../codec/index.js";
17
17
  import {
18
18
  type DeltaDetachedNodeBuild,
19
19
  type DeltaFieldChanges,
@@ -60,9 +60,10 @@ export class ForestSummarizer implements Summarizable {
60
60
  private readonly revisionTagCodec: RevisionTagCodec,
61
61
  fieldBatchCodec: FieldBatchCodec,
62
62
  private readonly encoderContext: FieldBatchEncodingContext,
63
- options: ICodecOptions = { jsonValidator: noopValidator },
63
+ options: CodecWriteOptions,
64
64
  private readonly idCompressor: IIdCompressor,
65
65
  ) {
66
+ // TODO: this should take in CodecWriteOptions, and use it to pick the write version.
66
67
  this.codec = makeForestSummarizerCodec(options, fieldBatchCodec);
67
68
  }
68
69
 
@@ -15,6 +15,11 @@ export {
15
15
  cursorForMapTreeNode,
16
16
  mapTreeFromCursor,
17
17
  mapTreeFieldFromCursor,
18
+ type MinimalMapTreeNodeView,
19
+ mapTreeFieldsWithField,
20
+ mapTreeWithField,
21
+ type MapTreeFieldViewGeneric,
22
+ type MapTreeNodeViewGeneric,
18
23
  } from "./mapTreeCursor.js";
19
24
  export { buildForest } from "./object-forest/index.js";
20
25
  export {
@@ -174,6 +179,10 @@ export {
174
179
  treeStatusFromAnchorCache,
175
180
  indexForAt,
176
181
  FlexTreeEntityKind,
182
+ type FlexibleNodeContent,
183
+ type FlexibleFieldContent,
184
+ type FlexTreeHydratedContextMinimal,
185
+ type HydratedFlexTreeNode,
177
186
  } from "./flex-tree/index.js";
178
187
 
179
188
  export { TreeCompressionStrategy } from "./treeCompressionUtils.js";
@@ -12,49 +12,136 @@ import {
12
12
  type FieldKey,
13
13
  type ITreeCursor,
14
14
  type MapTree,
15
+ type NodeData,
15
16
  aboveRootPlaceholder,
16
17
  detachedFieldAsKey,
17
18
  mapCursorField,
18
19
  rootField,
20
+ rootFieldKey,
19
21
  } from "../core/index.js";
20
22
 
21
23
  import {
22
24
  type CursorAdapter,
23
25
  type CursorWithNode,
26
+ type Field,
24
27
  stackTreeFieldCursor,
25
28
  stackTreeNodeCursor,
26
29
  } from "./treeCursorUtils.js";
30
+ import type { requireAssignableTo } from "../util/index.js";
31
+
32
+ /**
33
+ * A generic variant of {@link MapTree} that can be used to strongly type trees implementing a MapTree-like API.
34
+ * @remarks
35
+ * Due to how TypeScript handles recursive generic types, explicitly named extension interfaces work best for parameterizing this, and a default type parameter can't be provided.
36
+ * @see {@link MinimalMapTreeNodeView} for a minimal configuration of this interface.
37
+ */
38
+ export interface MapTreeNodeViewGeneric<TNode> extends NodeData {
39
+ /**
40
+ * The non-empty fields on this node.
41
+ * @remarks
42
+ * This is the subset of map needed to view the tree.
43
+ * Theoretically `Symbol.iterator` and "keys" are redundant.
44
+ */
45
+ readonly fields: Pick<
46
+ Map<FieldKey, MapTreeFieldViewGeneric<TNode>>,
47
+ typeof Symbol.iterator | "get"
48
+ >;
49
+ }
50
+
51
+ /**
52
+ * A field in {@link MapTreeNodeViewGeneric}.
53
+ */
54
+ export type MapTreeFieldViewGeneric<TNode> = Pick<
55
+ readonly TNode[],
56
+ typeof Symbol.iterator | "length"
57
+ >;
58
+
59
+ /**
60
+ * Like {@link MapTree} but with the minimal properties needed for reading.
61
+ */
62
+ export interface MinimalMapTreeNodeView
63
+ extends MapTreeNodeViewGeneric<MinimalMapTreeNodeView> {}
64
+
65
+ {
66
+ // Check that these interfaces are subsets of MapTree as intended:
67
+ type _check1 = requireAssignableTo<MapTree, MinimalMapTreeNodeView>;
68
+ type _check2 = requireAssignableTo<MapTree, MapTreeNodeViewGeneric<MapTree>>;
69
+ }
27
70
 
28
71
  /**
29
72
  * Returns an {@link ITreeCursorSynchronous} in nodes mode for a single {@link MapTree}.
30
73
  */
31
- export function cursorForMapTreeNode(root: MapTree): CursorWithNode<MapTree> {
32
- return stackTreeNodeCursor(adapter, root);
74
+ export function cursorForMapTreeNode<T extends MapTreeNodeViewGeneric<T>>(
75
+ root: T,
76
+ ): CursorWithNode<T> {
77
+ // There doesn't seem to be a clean way to get TypeScript to type check this without casting
78
+ // without declaring the adapter inside this generic function and needlessly recreating it on every call.
79
+ const adapterTyped = adapter as CursorAdapter<MapTreeNodeViewGeneric<T>> as CursorAdapter<T>;
80
+ return stackTreeNodeCursor(adapterTyped, root);
81
+ }
82
+
83
+ /**
84
+ * Creates an {@link ExclusiveMapTree} with a single field and no value.
85
+ * @remarks
86
+ * This handles ensuring the field is omitted if empty, and defaults to making the node above the root.
87
+ */
88
+ export function mapTreeWithField(
89
+ children: ExclusiveMapTree[],
90
+ key = rootFieldKey,
91
+ type = aboveRootPlaceholder,
92
+ ): ExclusiveMapTree {
93
+ return {
94
+ type,
95
+ fields: mapTreeFieldsWithField(children, key),
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Creates a Map suitable for use as {@link MapTree.fields} with a single field.
101
+ * @remarks
102
+ * This handles ensuring the field is omitted if empty.
103
+ */
104
+ export function mapTreeFieldsWithField<T extends readonly unknown[]>(
105
+ children: T,
106
+ key: FieldKey,
107
+ ): Map<FieldKey, T> {
108
+ return new Map(children.length === 0 ? [] : [[key, children]]);
33
109
  }
34
110
 
35
111
  /**
36
112
  * Returns an {@link ITreeCursorSynchronous} in fields mode for a MapTree field.
37
113
  */
38
- export function cursorForMapTreeField(
39
- root: readonly MapTree[],
114
+ export function cursorForMapTreeField<T extends MapTreeNodeViewGeneric<T>>(
115
+ root: readonly T[],
40
116
  detachedField: DetachedField = rootField,
41
- ): CursorWithNode<MapTree> {
117
+ ): CursorWithNode<T> {
42
118
  const key = detachedFieldAsKey(detachedField);
43
- return stackTreeFieldCursor(
44
- adapter,
45
- {
46
- type: aboveRootPlaceholder,
47
- fields: new Map([[key, root]]),
48
- },
49
- detachedField,
50
- );
119
+ const adapterTyped = adapter as unknown as CursorAdapter<T>;
120
+ const dummyRoot: MapTreeNodeViewGeneric<T> = {
121
+ type: aboveRootPlaceholder,
122
+ fields: mapTreeFieldsWithField(root, key),
123
+ };
124
+ return stackTreeFieldCursor(adapterTyped, dummyRoot as T, detachedField);
51
125
  }
52
126
 
53
- const adapter: CursorAdapter<MapTree> = {
127
+ const adapter: CursorAdapter<MinimalMapTreeNodeView> = {
54
128
  value: (node) => node.value,
55
129
  type: (node) => node.type,
56
- keysFromNode: (node) => [...node.fields.keys()], // TODO: don't convert this to array here.
57
- getFieldFromNode: (node, key) => node.fields.get(key) ?? [],
130
+ keysFromNode: (node) => Array.from(node.fields, ([key, field]) => key),
131
+ getFieldFromNode: (node, key): Field<MinimalMapTreeNodeView> => {
132
+ const field = node.fields.get(key) as
133
+ | MinimalMapTreeNodeView[]
134
+ | Iterable<MinimalMapTreeNodeView>
135
+ | undefined;
136
+ if (field === undefined) {
137
+ return [];
138
+ }
139
+ if (Array.isArray(field)) {
140
+ return field as readonly MinimalMapTreeNodeView[];
141
+ }
142
+ // TODO: this copy could be avoided by using Array.at instead of indexing in `Field`, but that requires ES2022.
143
+ return [...field] as readonly MinimalMapTreeNodeView[];
144
+ },
58
145
  };
59
146
 
60
147
  /**
@@ -76,7 +76,7 @@ export function makeModularChangeCodecFamily(
76
76
  ChangeEncodingContext
77
77
  >,
78
78
  fieldsCodec: FieldBatchCodec,
79
- { jsonValidator: validator }: ICodecOptions,
79
+ codecOptions: ICodecOptions,
80
80
  chunkCompressionStrategy: TreeCompressionStrategy = TreeCompressionStrategy.Compressed,
81
81
  ): ICodecFamily<ModularChangeset, ChangeEncodingContext> {
82
82
  return makeCodecFamily(
@@ -86,7 +86,7 @@ export function makeModularChangeCodecFamily(
86
86
  fieldKinds,
87
87
  revisionTagCodec,
88
88
  fieldsCodec,
89
- { jsonValidator: validator },
89
+ codecOptions,
90
90
  chunkCompressionStrategy,
91
91
  ),
92
92
  ]),
@@ -116,7 +116,7 @@ function makeModularChangeCodec(
116
116
  ChangeEncodingContext
117
117
  >,
118
118
  fieldsCodec: FieldBatchCodec,
119
- { jsonValidator: validator }: ICodecOptions,
119
+ codecOptions: ICodecOptions,
120
120
  chunkCompressionStrategy: TreeCompressionStrategy = TreeCompressionStrategy.Compressed,
121
121
  ): ModularChangeCodec {
122
122
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -125,7 +125,7 @@ function makeModularChangeCodec(
125
125
  return {
126
126
  codec,
127
127
  compiledSchema: codec.json.encodedSchema
128
- ? validator.compile(codec.json.encodedSchema)
128
+ ? codecOptions.jsonValidator.compile(codec.json.encodedSchema)
129
129
  : undefined,
130
130
  };
131
131
  };
@@ -519,7 +519,11 @@ function makeModularChangeCodec(
519
519
  },
520
520
  };
521
521
 
522
- return withSchemaValidation(EncodedModularChangeset, modularChangeCodec, validator);
522
+ return withSchemaValidation(
523
+ EncodedModularChangeset,
524
+ modularChangeCodec,
525
+ codecOptions.jsonValidator,
526
+ );
523
527
  }
524
528
 
525
529
  function getChangeHandler(
@@ -72,6 +72,11 @@ export function stackTreeFieldCursor<TNode>(
72
72
  return cursor;
73
73
  }
74
74
 
75
+ /**
76
+ * The representation of a field used by {@link CursorAdapter}.
77
+ */
78
+ export type Field<TNode> = Pick<readonly TNode[], typeof Symbol.iterator | "length" | number>;
79
+
75
80
  /**
76
81
  * Provides functionality to allow a {@link stackTreeNodeCursor} and {@link stackTreeFieldCursor} to implement cursors.
77
82
  */
@@ -91,10 +96,10 @@ export interface CursorAdapter<TNode> {
91
96
  /**
92
97
  * @returns the child nodes for the given node and key.
93
98
  */
94
- getFieldFromNode(node: TNode, key: FieldKey): readonly TNode[];
99
+ getFieldFromNode(node: TNode, key: FieldKey): Field<TNode>;
95
100
  }
96
101
 
97
- type SiblingsOrKey<TNode> = readonly TNode[] | readonly FieldKey[];
102
+ type SiblingsOrKey<TNode> = Field<TNode> | readonly FieldKey[];
98
103
 
99
104
  /**
100
105
  * A class that satisfies part of the ITreeCursorSynchronous implementation.
@@ -122,7 +127,7 @@ export abstract class SynchronousCursor {
122
127
  * 2. Support for cursors which are field cursors at the root.
123
128
  */
124
129
  class StackCursor<TNode> extends SynchronousCursor implements CursorWithNode<TNode> {
125
- public readonly [CursorMarker] = true;
130
+ public override readonly [CursorMarker] = true;
126
131
  /**
127
132
  * Might start at special root where fields are detached sequences.
128
133
  *
@@ -149,14 +154,18 @@ class StackCursor<TNode> extends SynchronousCursor implements CursorWithNode<TNo
149
154
  debugAssert(() =>
150
155
  this.mode === CursorLocationType.Fields ? true : "must be in fields mode",
151
156
  );
152
- return this.siblings[this.index] as FieldKey;
157
+ // index is kept inbounds as an invariant of the class.
158
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
159
+ return (this.siblings as readonly FieldKey[])[this.index]!;
153
160
  }
154
161
 
155
162
  private getStackedFieldKey(height: number): FieldKey {
156
163
  assert(height % 2 === 1, 0x3b8 /* must field height */);
157
164
  const siblingStack = this.siblingStack[height] ?? oob();
158
165
  const indexStack = this.indexStack[height] ?? oob();
159
- return siblingStack[indexStack] as FieldKey;
166
+ // index is kept inbounds as an invariant of the class.
167
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
168
+ return (siblingStack as readonly FieldKey[])[indexStack]!;
160
169
  }
161
170
 
162
171
  private getStackedNodeIndex(height: number): number {
@@ -166,9 +175,10 @@ class StackCursor<TNode> extends SynchronousCursor implements CursorWithNode<TNo
166
175
 
167
176
  private getStackedNode(height: number): TNode {
168
177
  const index = this.getStackedNodeIndex(height);
169
- // Test is failing when using `?? oob()` here.
178
+ // Can not use `?? oob()` since null and undefined are valid values.
179
+ // index is kept inbounds as an invariant of the class.
170
180
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
171
- return (this.siblingStack[height] as readonly TNode[])[index]!;
181
+ return (this.siblingStack[height] as Field<TNode>)[index]!;
172
182
  }
173
183
 
174
184
  public getFieldLength(): number {
@@ -358,12 +368,13 @@ class StackCursor<TNode> extends SynchronousCursor implements CursorWithNode<TNo
358
368
 
359
369
  public getNode(): TNode {
360
370
  // assert(this.mode === CursorLocationType.Nodes, "can only get node when in node");
361
- // Test is failing when using `?? oob()` here.
371
+ // Can not use `?? oob()` since null and undefined are valid values.
372
+ // index is kept inbounds as an invariant of the class.
362
373
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
363
- return (this.siblings as TNode[])[this.index]!;
374
+ return (this.siblings as Field<TNode>)[this.index]!;
364
375
  }
365
376
 
366
- private getField(): readonly TNode[] {
377
+ private getField(): Field<TNode> {
367
378
  // assert(this.mode === CursorLocationType.Fields, "can only get field when in fields");
368
379
  const parent = this.getStackedNode(this.indexStack.length - 1);
369
380
  const key: FieldKey = this.getFieldKey();
package/src/index.ts CHANGED
@@ -255,6 +255,7 @@ export { persistedToSimpleSchema } from "./shared-tree/index.js";
255
255
 
256
256
  export {
257
257
  type ICodecOptions,
258
+ type CodecWriteOptions,
258
259
  type JsonValidator,
259
260
  type SchemaValidationFunction,
260
261
  FluidClientVersion,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/tree";
9
- export const pkgVersion = "2.41.0";
9
+ export const pkgVersion = "2.42.0";