@fluidframework/tree 2.70.0-361092 → 2.70.0-361788

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 (360) hide show
  1. package/api-report/tree.alpha.api.md +36 -17
  2. package/api-report/tree.beta.api.md +70 -2
  3. package/api-report/tree.legacy.beta.api.md +70 -2
  4. package/dist/alpha.d.ts +15 -11
  5. package/dist/api.d.ts +6 -1
  6. package/dist/api.d.ts.map +1 -1
  7. package/dist/api.js +9 -1
  8. package/dist/api.js.map +1 -1
  9. package/dist/beta.d.ts +13 -0
  10. package/dist/codec/codec.d.ts +3 -3
  11. package/dist/codec/codec.js.map +1 -1
  12. package/dist/core/forest/forest.d.ts +3 -4
  13. package/dist/core/forest/forest.d.ts.map +1 -1
  14. package/dist/core/forest/forest.js.map +1 -1
  15. package/dist/core/rebase/changeRebaser.d.ts +1 -1
  16. package/dist/core/rebase/changeRebaser.js.map +1 -1
  17. package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
  18. package/dist/core/tree/detachedFieldIndex.js +4 -1
  19. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  20. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +6 -0
  21. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  22. package/dist/feature-libraries/chunked-forest/chunkTree.js +11 -2
  23. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  24. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -1
  25. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  26. package/dist/feature-libraries/chunked-forest/chunkedForest.js +1 -1
  27. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  28. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +21 -20
  29. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  30. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +17 -43
  31. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  32. package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
  33. package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  34. package/dist/feature-libraries/chunked-forest/index.js +2 -1
  35. package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
  36. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  37. package/dist/feature-libraries/flex-tree/lazyField.js +2 -1
  38. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  39. package/dist/feature-libraries/flex-tree/utilities.d.ts +1 -1
  40. package/dist/feature-libraries/flex-tree/utilities.js +1 -1
  41. package/dist/feature-libraries/flex-tree/utilities.js.map +1 -1
  42. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
  43. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  44. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +42 -47
  45. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  46. package/dist/feature-libraries/incrementalSummarizationUtils.d.ts +1 -1
  47. package/dist/feature-libraries/incrementalSummarizationUtils.js.map +1 -1
  48. package/dist/feature-libraries/index.d.ts +1 -1
  49. package/dist/feature-libraries/index.d.ts.map +1 -1
  50. package/dist/feature-libraries/index.js +2 -1
  51. package/dist/feature-libraries/index.js.map +1 -1
  52. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +1 -1
  53. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
  54. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  55. package/dist/feature-libraries/object-forest/objectForest.d.ts +1 -1
  56. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  57. package/dist/feature-libraries/object-forest/objectForest.js +1 -1
  58. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  59. package/dist/feature-libraries/sequence-field/formatV1.d.ts +1 -1
  60. package/dist/feature-libraries/sequence-field/formatV1.js.map +1 -1
  61. package/dist/feature-libraries/sequence-field/formatV2.d.ts +1 -1
  62. package/dist/feature-libraries/sequence-field/formatV2.js.map +1 -1
  63. package/dist/feature-libraries/sequence-field/formatV3.d.ts +1 -1
  64. package/dist/feature-libraries/sequence-field/formatV3.js.map +1 -1
  65. package/dist/index.d.ts +2 -2
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +4 -2
  68. package/dist/index.js.map +1 -1
  69. package/dist/legacy.d.ts +13 -0
  70. package/dist/packageVersion.d.ts +1 -1
  71. package/dist/packageVersion.js +1 -1
  72. package/dist/packageVersion.js.map +1 -1
  73. package/dist/shared-tree/independentView.d.ts.map +1 -1
  74. package/dist/shared-tree/independentView.js +2 -1
  75. package/dist/shared-tree/independentView.js.map +1 -1
  76. package/dist/shared-tree/schematizingTreeView.d.ts +4 -3
  77. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  78. package/dist/shared-tree/schematizingTreeView.js +1 -1
  79. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  80. package/dist/shared-tree/sharedTree.d.ts +1 -1
  81. package/dist/shared-tree/sharedTree.js +1 -1
  82. package/dist/shared-tree/sharedTree.js.map +1 -1
  83. package/dist/shared-tree/treeAlpha.d.ts +28 -2
  84. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  85. package/dist/shared-tree/treeAlpha.js +12 -0
  86. package/dist/shared-tree/treeAlpha.js.map +1 -1
  87. package/dist/shared-tree/treeCheckout.d.ts +1 -1
  88. package/dist/shared-tree/treeCheckout.js +1 -1
  89. package/dist/shared-tree/treeCheckout.js.map +1 -1
  90. package/dist/shared-tree-core/sharedTreeCore.js +1 -1
  91. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  92. package/dist/shared-tree-core/transaction.d.ts +2 -2
  93. package/dist/shared-tree-core/transaction.js.map +1 -1
  94. package/dist/simple-tree/api/incrementalAllowedTypes.d.ts +47 -0
  95. package/dist/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -0
  96. package/dist/simple-tree/api/incrementalAllowedTypes.js +90 -0
  97. package/dist/simple-tree/api/incrementalAllowedTypes.js.map +1 -0
  98. package/dist/simple-tree/api/index.d.ts +2 -1
  99. package/dist/simple-tree/api/index.d.ts.map +1 -1
  100. package/dist/simple-tree/api/index.js +4 -1
  101. package/dist/simple-tree/api/index.js.map +1 -1
  102. package/dist/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
  103. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  104. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  105. package/dist/simple-tree/api/tree.d.ts +51 -37
  106. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  107. package/dist/simple-tree/api/tree.js.map +1 -1
  108. package/dist/simple-tree/core/allowedTypes.d.ts +10 -11
  109. package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
  110. package/dist/simple-tree/core/allowedTypes.js +1 -1
  111. package/dist/simple-tree/core/allowedTypes.js.map +1 -1
  112. package/dist/simple-tree/core/index.d.ts +1 -1
  113. package/dist/simple-tree/core/index.d.ts.map +1 -1
  114. package/dist/simple-tree/core/index.js +2 -1
  115. package/dist/simple-tree/core/index.js.map +1 -1
  116. package/dist/simple-tree/core/treeNodeSchema.d.ts +3 -8
  117. package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  118. package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
  119. package/dist/simple-tree/core/treeNodeValid.d.ts +2 -2
  120. package/dist/simple-tree/core/treeNodeValid.d.ts.map +1 -1
  121. package/dist/simple-tree/core/treeNodeValid.js +2 -2
  122. package/dist/simple-tree/core/treeNodeValid.js.map +1 -1
  123. package/dist/simple-tree/core/walkSchema.d.ts.map +1 -1
  124. package/dist/simple-tree/core/walkSchema.js +1 -1
  125. package/dist/simple-tree/core/walkSchema.js.map +1 -1
  126. package/dist/simple-tree/core/withType.d.ts +20 -0
  127. package/dist/simple-tree/core/withType.d.ts.map +1 -1
  128. package/dist/simple-tree/core/withType.js +21 -1
  129. package/dist/simple-tree/core/withType.js.map +1 -1
  130. package/dist/simple-tree/createContext.d.ts.map +1 -1
  131. package/dist/simple-tree/createContext.js +1 -1
  132. package/dist/simple-tree/createContext.js.map +1 -1
  133. package/dist/simple-tree/index.d.ts +2 -2
  134. package/dist/simple-tree/index.d.ts.map +1 -1
  135. package/dist/simple-tree/index.js +5 -2
  136. package/dist/simple-tree/index.js.map +1 -1
  137. package/dist/simple-tree/leafNodeSchema.js +1 -1
  138. package/dist/simple-tree/leafNodeSchema.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 +1 -1
  141. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  142. package/dist/simple-tree/node-kinds/map/mapNode.js +1 -1
  143. package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  144. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  145. package/dist/simple-tree/node-kinds/object/objectNode.js +1 -1
  146. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  147. package/dist/simple-tree/node-kinds/record/recordNode.js +1 -1
  148. package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  149. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +1 -0
  150. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  151. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +12 -0
  152. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  153. package/dist/util/nestedMap.d.ts +1 -1
  154. package/dist/util/nestedMap.js +1 -1
  155. package/dist/util/nestedMap.js.map +1 -1
  156. package/dist/util/referenceCounting.d.ts +1 -1
  157. package/dist/util/referenceCounting.js.map +1 -1
  158. package/lib/alpha.d.ts +15 -11
  159. package/lib/api.d.ts +6 -1
  160. package/lib/api.d.ts.map +1 -1
  161. package/lib/api.js +7 -0
  162. package/lib/api.js.map +1 -1
  163. package/lib/beta.d.ts +13 -0
  164. package/lib/codec/codec.d.ts +3 -3
  165. package/lib/codec/codec.js.map +1 -1
  166. package/lib/core/forest/forest.d.ts +3 -4
  167. package/lib/core/forest/forest.d.ts.map +1 -1
  168. package/lib/core/forest/forest.js.map +1 -1
  169. package/lib/core/rebase/changeRebaser.d.ts +1 -1
  170. package/lib/core/rebase/changeRebaser.js.map +1 -1
  171. package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
  172. package/lib/core/tree/detachedFieldIndex.js +4 -1
  173. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  174. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +6 -0
  175. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  176. package/lib/feature-libraries/chunked-forest/chunkTree.js +8 -0
  177. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  178. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -1
  179. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  180. package/lib/feature-libraries/chunked-forest/chunkedForest.js +2 -2
  181. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  182. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +21 -20
  183. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  184. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +17 -43
  185. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  186. package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
  187. package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  188. package/lib/feature-libraries/chunked-forest/index.js +1 -1
  189. package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
  190. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  191. package/lib/feature-libraries/flex-tree/lazyField.js +2 -1
  192. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  193. package/lib/feature-libraries/flex-tree/utilities.d.ts +1 -1
  194. package/lib/feature-libraries/flex-tree/utilities.js +1 -1
  195. package/lib/feature-libraries/flex-tree/utilities.js.map +1 -1
  196. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
  197. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  198. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +42 -47
  199. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  200. package/lib/feature-libraries/incrementalSummarizationUtils.d.ts +1 -1
  201. package/lib/feature-libraries/incrementalSummarizationUtils.js.map +1 -1
  202. package/lib/feature-libraries/index.d.ts +1 -1
  203. package/lib/feature-libraries/index.d.ts.map +1 -1
  204. package/lib/feature-libraries/index.js +1 -1
  205. package/lib/feature-libraries/index.js.map +1 -1
  206. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +1 -1
  207. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
  208. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  209. package/lib/feature-libraries/object-forest/objectForest.d.ts +1 -1
  210. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  211. package/lib/feature-libraries/object-forest/objectForest.js +2 -2
  212. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  213. package/lib/feature-libraries/sequence-field/formatV1.d.ts +1 -1
  214. package/lib/feature-libraries/sequence-field/formatV1.js.map +1 -1
  215. package/lib/feature-libraries/sequence-field/formatV2.d.ts +1 -1
  216. package/lib/feature-libraries/sequence-field/formatV2.js.map +1 -1
  217. package/lib/feature-libraries/sequence-field/formatV3.d.ts +1 -1
  218. package/lib/feature-libraries/sequence-field/formatV3.js.map +1 -1
  219. package/lib/index.d.ts +2 -2
  220. package/lib/index.d.ts.map +1 -1
  221. package/lib/index.js +2 -2
  222. package/lib/index.js.map +1 -1
  223. package/lib/legacy.d.ts +13 -0
  224. package/lib/packageVersion.d.ts +1 -1
  225. package/lib/packageVersion.js +1 -1
  226. package/lib/packageVersion.js.map +1 -1
  227. package/lib/shared-tree/independentView.d.ts.map +1 -1
  228. package/lib/shared-tree/independentView.js +2 -1
  229. package/lib/shared-tree/independentView.js.map +1 -1
  230. package/lib/shared-tree/schematizingTreeView.d.ts +4 -3
  231. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  232. package/lib/shared-tree/schematizingTreeView.js +2 -2
  233. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  234. package/lib/shared-tree/sharedTree.d.ts +1 -1
  235. package/lib/shared-tree/sharedTree.js +1 -1
  236. package/lib/shared-tree/sharedTree.js.map +1 -1
  237. package/lib/shared-tree/treeAlpha.d.ts +28 -2
  238. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  239. package/lib/shared-tree/treeAlpha.js +13 -1
  240. package/lib/shared-tree/treeAlpha.js.map +1 -1
  241. package/lib/shared-tree/treeCheckout.d.ts +1 -1
  242. package/lib/shared-tree/treeCheckout.js +1 -1
  243. package/lib/shared-tree/treeCheckout.js.map +1 -1
  244. package/lib/shared-tree-core/sharedTreeCore.js +1 -1
  245. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  246. package/lib/shared-tree-core/transaction.d.ts +2 -2
  247. package/lib/shared-tree-core/transaction.js.map +1 -1
  248. package/lib/simple-tree/api/incrementalAllowedTypes.d.ts +47 -0
  249. package/lib/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -0
  250. package/lib/simple-tree/api/incrementalAllowedTypes.js +86 -0
  251. package/lib/simple-tree/api/incrementalAllowedTypes.js.map +1 -0
  252. package/lib/simple-tree/api/index.d.ts +2 -1
  253. package/lib/simple-tree/api/index.d.ts.map +1 -1
  254. package/lib/simple-tree/api/index.js +1 -0
  255. package/lib/simple-tree/api/index.js.map +1 -1
  256. package/lib/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
  257. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  258. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  259. package/lib/simple-tree/api/tree.d.ts +51 -37
  260. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  261. package/lib/simple-tree/api/tree.js.map +1 -1
  262. package/lib/simple-tree/core/allowedTypes.d.ts +10 -11
  263. package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
  264. package/lib/simple-tree/core/allowedTypes.js +1 -1
  265. package/lib/simple-tree/core/allowedTypes.js.map +1 -1
  266. package/lib/simple-tree/core/index.d.ts +1 -1
  267. package/lib/simple-tree/core/index.d.ts.map +1 -1
  268. package/lib/simple-tree/core/index.js +1 -1
  269. package/lib/simple-tree/core/index.js.map +1 -1
  270. package/lib/simple-tree/core/treeNodeSchema.d.ts +3 -8
  271. package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  272. package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
  273. package/lib/simple-tree/core/treeNodeValid.d.ts +2 -2
  274. package/lib/simple-tree/core/treeNodeValid.d.ts.map +1 -1
  275. package/lib/simple-tree/core/treeNodeValid.js +2 -2
  276. package/lib/simple-tree/core/treeNodeValid.js.map +1 -1
  277. package/lib/simple-tree/core/walkSchema.d.ts.map +1 -1
  278. package/lib/simple-tree/core/walkSchema.js +1 -1
  279. package/lib/simple-tree/core/walkSchema.js.map +1 -1
  280. package/lib/simple-tree/core/withType.d.ts +20 -0
  281. package/lib/simple-tree/core/withType.d.ts.map +1 -1
  282. package/lib/simple-tree/core/withType.js +20 -0
  283. package/lib/simple-tree/core/withType.js.map +1 -1
  284. package/lib/simple-tree/createContext.d.ts.map +1 -1
  285. package/lib/simple-tree/createContext.js +2 -2
  286. package/lib/simple-tree/createContext.js.map +1 -1
  287. package/lib/simple-tree/index.d.ts +2 -2
  288. package/lib/simple-tree/index.d.ts.map +1 -1
  289. package/lib/simple-tree/index.js +2 -2
  290. package/lib/simple-tree/index.js.map +1 -1
  291. package/lib/simple-tree/leafNodeSchema.js +1 -1
  292. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  293. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  294. package/lib/simple-tree/node-kinds/array/arrayNode.js +1 -1
  295. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  296. package/lib/simple-tree/node-kinds/map/mapNode.js +1 -1
  297. package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  298. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  299. package/lib/simple-tree/node-kinds/object/objectNode.js +1 -1
  300. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  301. package/lib/simple-tree/node-kinds/record/recordNode.js +1 -1
  302. package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  303. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +1 -0
  304. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  305. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +13 -1
  306. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  307. package/lib/util/nestedMap.d.ts +1 -1
  308. package/lib/util/nestedMap.js +1 -1
  309. package/lib/util/nestedMap.js.map +1 -1
  310. package/lib/util/referenceCounting.d.ts +1 -1
  311. package/lib/util/referenceCounting.js.map +1 -1
  312. package/package.json +21 -21
  313. package/src/api.ts +11 -0
  314. package/src/codec/codec.ts +3 -3
  315. package/src/core/forest/forest.ts +3 -4
  316. package/src/core/rebase/changeRebaser.ts +1 -1
  317. package/src/core/tree/detachedFieldIndex.ts +4 -1
  318. package/src/feature-libraries/chunked-forest/chunkTree.ts +9 -0
  319. package/src/feature-libraries/chunked-forest/chunkedForest.ts +3 -3
  320. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +20 -58
  321. package/src/feature-libraries/chunked-forest/index.ts +1 -0
  322. package/src/feature-libraries/flex-tree/lazyField.ts +3 -1
  323. package/src/feature-libraries/flex-tree/utilities.ts +1 -1
  324. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +64 -70
  325. package/src/feature-libraries/incrementalSummarizationUtils.ts +1 -1
  326. package/src/feature-libraries/index.ts +1 -0
  327. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1 -1
  328. package/src/feature-libraries/object-forest/objectForest.ts +3 -3
  329. package/src/feature-libraries/sequence-field/formatV1.ts +1 -1
  330. package/src/feature-libraries/sequence-field/formatV2.ts +1 -1
  331. package/src/feature-libraries/sequence-field/formatV3.ts +1 -1
  332. package/src/index.ts +4 -1
  333. package/src/packageVersion.ts +1 -1
  334. package/src/shared-tree/independentView.ts +4 -1
  335. package/src/shared-tree/schematizingTreeView.ts +10 -5
  336. package/src/shared-tree/sharedTree.ts +1 -1
  337. package/src/shared-tree/treeAlpha.ts +50 -2
  338. package/src/shared-tree/treeCheckout.ts +1 -1
  339. package/src/shared-tree-core/sharedTreeCore.ts +1 -1
  340. package/src/shared-tree-core/transaction.ts +2 -2
  341. package/src/simple-tree/api/incrementalAllowedTypes.ts +107 -0
  342. package/src/simple-tree/api/index.ts +6 -0
  343. package/src/simple-tree/api/schemaFactoryBeta.ts +6 -2
  344. package/src/simple-tree/api/tree.ts +64 -44
  345. package/src/simple-tree/core/allowedTypes.ts +10 -11
  346. package/src/simple-tree/core/index.ts +6 -1
  347. package/src/simple-tree/core/treeNodeSchema.ts +3 -8
  348. package/src/simple-tree/core/treeNodeValid.ts +3 -3
  349. package/src/simple-tree/core/walkSchema.ts +1 -2
  350. package/src/simple-tree/core/withType.ts +24 -0
  351. package/src/simple-tree/createContext.ts +1 -4
  352. package/src/simple-tree/index.ts +5 -0
  353. package/src/simple-tree/leafNodeSchema.ts +1 -1
  354. package/src/simple-tree/node-kinds/array/arrayNode.ts +5 -2
  355. package/src/simple-tree/node-kinds/map/mapNode.ts +1 -1
  356. package/src/simple-tree/node-kinds/object/objectNode.ts +1 -4
  357. package/src/simple-tree/node-kinds/record/recordNode.ts +1 -1
  358. package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +13 -0
  359. package/src/util/nestedMap.ts +1 -1
  360. package/src/util/referenceCounting.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"nestedMap.js","sourceRoot":"","sources":["../../src/util/nestedMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { oob } from \"@fluidframework/core-utils/internal\";\n\nimport { getOrAddInMap, getOrCreate } from \"./utils.js\";\n\n/**\n * A dictionary whose values are keyed off of two objects (key1, key2).\n * As it is a nested map, size() will return the number of distinct key1s.\n * If you need constant-time access to the number of values, use SizedNestedMap instead.\n *\n * This code assumes values will not be undefined (keys can be undefined).\n */\nexport type NestedMap<Key1, Key2, Value> = Map<Key1, Map<Key2, Value>>;\n\n/**\n * A read-only version of {@link NestedMap}.\n */\nexport type ReadonlyNestedMap<Key1, Key2, Value> = ReadonlyMap<Key1, ReadonlyMap<Key2, Value>>;\n\n/**\n * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is returned.\n */\nexport function tryAddToNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): Value | undefined {\n\tlet innerMap = map.get(key1);\n\tif (innerMap === undefined) {\n\t\tinnerMap = new Map();\n\t\tmap.set(key1, innerMap);\n\t}\n\tif (innerMap.has(key2)) {\n\t\treturn innerMap.get(key2);\n\t}\n\tinnerMap.set(key2, value);\n\treturn undefined;\n}\n\n/**\n * Copies over all entries from the source map into the destination map.\n *\n * @param source - The map to copy data from. Not mutated.\n * @param destination - The map to copy data into. Both the outer and inner map may be mutated.\n * @param override - Whether existing entries in `destination` should be replaced by corresponding entries in `source`.\n *\n * @remarks - This function performs deep copying when necessary.\n * This ensures that mutating `destination` after this call will not result in unexpected mutations to `source`.\n */\nexport function populateNestedMap<Key1, Key2, Value>(\n\tsource: ReadonlyNestedMap<Key1, Key2, Value>,\n\tdestination: NestedMap<Key1, Key2, Value>,\n\toverride: boolean,\n): void {\n\tfor (const [key1, sourceInner] of source) {\n\t\tlet destinationInner = destination.get(key1);\n\t\tif (destinationInner === undefined) {\n\t\t\tdestinationInner = new Map(sourceInner);\n\t\t\tdestination.set(key1, destinationInner);\n\t\t} else {\n\t\t\tfor (const [key2, value] of sourceInner) {\n\t\t\t\tif (override || !destinationInner.has(key2)) {\n\t\t\t\t\tdestinationInner.set(key2, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Sets the value at (key1, key2) in map to value.\n * If there already is a value for (key1, key2), it is replaced with the provided one.\n */\nexport function setInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): void {\n\tconst innerMap = getOrAddInMap(map, key1, new Map<Key2, Value>());\n\tinnerMap.set(key2, value);\n}\n\n/**\n * {@link getOrCreate} for {@link NestedMap}.\n */\nexport function getOrCreateInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tdefaultValue: (key1: Key1, key2: Key2) => Value,\n): Value {\n\tconst innerMap = getOrAddInMap(map, key1, new Map<Key2, Value>());\n\treturn getOrCreate(innerMap, key2, (): Value => defaultValue(key1, key2));\n}\n\n/**\n * Returns the value at (key1, key2) in map, or undefined if not present.\n */\nexport function tryGetFromNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n): Value | undefined {\n\tconst innerMap = map.get(key1);\n\tif (innerMap === undefined) {\n\t\treturn undefined;\n\t}\n\treturn innerMap.get(key2);\n}\n\n/**\n * If (key1, key2) is not in the map, add value to the map.\n * Returns whatever is at (key1, key2) in map (which will be value if it was empty before).\n */\nexport function getOrAddInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): Value {\n\tconst existing = tryAddToNestedMap(map, key1, key2, value);\n\tif (existing !== undefined) {\n\t\treturn existing;\n\t}\n\treturn value;\n}\n\n/**\n * Does not change map.\n * If (key1, key2) is not in map, returns value.\n * If (key1, key2) is in map, return its entry.\n */\nexport function getOrDefaultInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): Value {\n\tconst existing = tryGetFromNestedMap(map, key1, key2);\n\tif (existing !== undefined) {\n\t\treturn existing;\n\t}\n\treturn value;\n}\n\n/**\n * Removes the value at (key1, key2) from the map.\n *\n * @returns true iff found.\n */\nexport function deleteFromNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n): boolean {\n\tconst innerMap = map.get(key1);\n\tif (innerMap === undefined) {\n\t\treturn false;\n\t}\n\tconst deleted = innerMap.delete(key2);\n\tif (innerMap.size === 0) {\n\t\tmap.delete(key1);\n\t}\n\treturn deleted;\n}\n\n/**\n * Converts a nested map to a flat list of triplets.\n */\nexport function nestedMapToFlatList<Key1, Key2, Value>(\n\tmap: ReadonlyNestedMap<Key1, Key2, Value>,\n): [Key1, Key2, Value][] {\n\tconst list: [Key1, Key2, Value][] = [];\n\tmap.forEach((innerMap, key1) => {\n\t\tinnerMap.forEach((val, key2) => {\n\t\t\tlist.push([key1, key2, val]);\n\t\t});\n\t});\n\treturn list;\n}\n\n/**\n * Builds a nested map from a flat list of triplets.\n */\nexport function nestedMapFromFlatList<Key1, Key2, Value>(\n\tlist: readonly (readonly [Key1, Key2, Value])[],\n): NestedMap<Key1, Key2, Value> {\n\tconst map = new Map<Key1, Map<Key2, Value>>();\n\tfor (const [key1, key2, val] of list) {\n\t\tgetOrAddInMap(map, key1, new Map<Key2, Value>()).set(key2, val);\n\t}\n\treturn map;\n}\n\nexport function forEachInNestedMap<Key1, Key2, Value>(\n\tmap: ReadonlyNestedMap<Key1, Key2, Value>,\n\tdelegate: (value: Value, key1: Key1, key2: Key2) => void,\n): void {\n\tmap.forEach((innerMap, keyFirst) => {\n\t\tinnerMap.forEach((val, keySecond) => {\n\t\t\tdelegate(val, keyFirst, keySecond);\n\t\t});\n\t});\n}\n\n/**\n * Maps the `input` map values using the provided `delegate`.\n *\n * @param input - The `NestedMap` whose contents are being mapped.\n * @param delegate - The delegate to use for mapping values,\n * @returns A new `NestedMap` with the same keys as `input`, but with the values produced by `delegate`.\n */\nexport function mapNestedMap<Key1, Key2, ValueIn, ValueOut = ValueIn>(\n\tinput: ReadonlyNestedMap<Key1, Key2, ValueIn>,\n\tdelegate: (value: ValueIn, key1: Key1, key2: Key2) => ValueOut,\n): NestedMap<Key1, Key2, ValueOut> {\n\tconst output = new Map<Key1, Map<Key2, ValueOut>>();\n\tinput.forEach((inputInnerMap, keyFirst) => {\n\t\tconst outputInnerMap = new Map<Key2, ValueOut>();\n\t\tinputInnerMap.forEach((val, keySecond) => {\n\t\t\tconst mappedValue = delegate(val, keyFirst, keySecond);\n\t\t\toutputInnerMap.set(keySecond, mappedValue);\n\t\t});\n\t\toutput.set(keyFirst, outputInnerMap);\n\t});\n\treturn output;\n}\n\n/**\n * Map with two keys; same semantics as NestedMap, but maintains a size count for the entire collection.\n * Note: undefined is not supported as a value, and will cause incorrect behavior.\n */\nexport class SizedNestedMap<Key1, Key2, Value> {\n\tprivate readonly nestedMap: NestedMap<Key1, Key2, Value> = new Map();\n\tprivate count = 0;\n\n\t/**\n\t * Returns the total number of elements in this nested map.\n\t */\n\tpublic get size(): number {\n\t\treturn this.count;\n\t}\n\n\t/**\n\t * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is\n\t * returned.\n\t */\n\tpublic tryGet(key1: Key1, key2: Key2): Value | undefined {\n\t\treturn tryGetFromNestedMap(this.nestedMap, key1, key2);\n\t}\n\n\t/**\n\t * Does not change map.\n\t * If (key1, key2) is not in map, returns value.\n\t * If (key1, key2) is in map, return its entry.\n\t */\n\tpublic getOrDefault(key1: Key1, key2: Key2, value: Value): Value {\n\t\treturn getOrDefaultInNestedMap(this.nestedMap, key1, key2, value);\n\t}\n\n\t/**\n\t * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is\n\t * returned.\n\t */\n\tpublic tryAdd(key1: Key1, key2: Key2, value: Value): Value | undefined {\n\t\tconst currentVal = tryAddToNestedMap(this.nestedMap, key1, key2, value);\n\t\tif (currentVal === undefined) {\n\t\t\tthis.count++;\n\t\t}\n\t\treturn currentVal;\n\t}\n\n\t/**\n\t * Sets the value at (key1, key2) in map to value.\n\t * If there already is a value for (key1, key2), it is replaced with the provided one.\n\t */\n\tpublic set(key1: Key1, key2: Key2, value: Value): void {\n\t\tif (this.tryAdd(key1, key2, value) !== undefined) {\n\t\t\tsetInNestedMap(this.nestedMap, key1, key2, value);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the value at (key1, key2) from the map.\n\t * Returns true iff found.\n\t */\n\tpublic delete(key1: Key1, key2: Key2): boolean {\n\t\tconst deleted = deleteFromNestedMap(this.nestedMap, key1, key2);\n\t\tif (deleted) {\n\t\t\tthis.count--;\n\t\t}\n\t\treturn deleted;\n\t}\n\n\t/**\n\t * Runs the supplied delegate for every (value, key1, key2).\n\t */\n\tpublic forEach(delegate: (value: Value, key1: Key1, key2: Key2) => void): void {\n\t\tforEachInNestedMap(this.nestedMap, delegate);\n\t}\n\n\t/**\n\t * Clears the map.\n\t */\n\tpublic clear(): void {\n\t\tthis.count = 0;\n\t\tthis.nestedMap.clear();\n\t}\n\n\tpublic values(): IterableIterator<Value> {\n\t\treturn (\n\t\t\tArray.from(this.nestedMap.values()).flatMap((innerMap) => innerMap.values())[0] ?? oob()\n\t\t);\n\t}\n\n\tpublic [Symbol.iterator](): IterableIterator<[Key1, Map<Key2, Value>]> {\n\t\treturn this.nestedMap[Symbol.iterator]();\n\t}\n}\n"]}
1
+ {"version":3,"file":"nestedMap.js","sourceRoot":"","sources":["../../src/util/nestedMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { oob } from \"@fluidframework/core-utils/internal\";\n\nimport { getOrAddInMap, getOrCreate } from \"./utils.js\";\n\n/**\n * A dictionary whose values are keyed off of two objects (key1, key2).\n * As it is a nested map, size() will return the number of distinct key1s.\n * If you need constant-time access to the number of values, use SizedNestedMap instead.\n *\n * This code assumes values will not be undefined (keys can be undefined).\n */\nexport type NestedMap<Key1, Key2, Value> = Map<Key1, Map<Key2, Value>>;\n\n/**\n * A read-only version of {@link NestedMap}.\n */\nexport type ReadonlyNestedMap<Key1, Key2, Value> = ReadonlyMap<Key1, ReadonlyMap<Key2, Value>>;\n\n/**\n * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is returned.\n */\nexport function tryAddToNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): Value | undefined {\n\tlet innerMap = map.get(key1);\n\tif (innerMap === undefined) {\n\t\tinnerMap = new Map();\n\t\tmap.set(key1, innerMap);\n\t}\n\tif (innerMap.has(key2)) {\n\t\treturn innerMap.get(key2);\n\t}\n\tinnerMap.set(key2, value);\n\treturn undefined;\n}\n\n/**\n * Copies over all entries from the source map into the destination map.\n *\n * @param source - The map to copy data from. Not mutated.\n * @param destination - The map to copy data into. Both the outer and inner map may be mutated.\n * @param override - Whether existing entries in `destination` should be replaced by corresponding entries in `source`.\n *\n * @remarks This function performs deep copying when necessary.\n * This ensures that mutating `destination` after this call will not result in unexpected mutations to `source`.\n */\nexport function populateNestedMap<Key1, Key2, Value>(\n\tsource: ReadonlyNestedMap<Key1, Key2, Value>,\n\tdestination: NestedMap<Key1, Key2, Value>,\n\toverride: boolean,\n): void {\n\tfor (const [key1, sourceInner] of source) {\n\t\tlet destinationInner = destination.get(key1);\n\t\tif (destinationInner === undefined) {\n\t\t\tdestinationInner = new Map(sourceInner);\n\t\t\tdestination.set(key1, destinationInner);\n\t\t} else {\n\t\t\tfor (const [key2, value] of sourceInner) {\n\t\t\t\tif (override || !destinationInner.has(key2)) {\n\t\t\t\t\tdestinationInner.set(key2, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Sets the value at (key1, key2) in map to value.\n * If there already is a value for (key1, key2), it is replaced with the provided one.\n */\nexport function setInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): void {\n\tconst innerMap = getOrAddInMap(map, key1, new Map<Key2, Value>());\n\tinnerMap.set(key2, value);\n}\n\n/**\n * {@link getOrCreate} for {@link NestedMap}.\n */\nexport function getOrCreateInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tdefaultValue: (key1: Key1, key2: Key2) => Value,\n): Value {\n\tconst innerMap = getOrAddInMap(map, key1, new Map<Key2, Value>());\n\treturn getOrCreate(innerMap, key2, (): Value => defaultValue(key1, key2));\n}\n\n/**\n * Returns the value at (key1, key2) in map, or undefined if not present.\n */\nexport function tryGetFromNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n): Value | undefined {\n\tconst innerMap = map.get(key1);\n\tif (innerMap === undefined) {\n\t\treturn undefined;\n\t}\n\treturn innerMap.get(key2);\n}\n\n/**\n * If (key1, key2) is not in the map, add value to the map.\n * Returns whatever is at (key1, key2) in map (which will be value if it was empty before).\n */\nexport function getOrAddInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): Value {\n\tconst existing = tryAddToNestedMap(map, key1, key2, value);\n\tif (existing !== undefined) {\n\t\treturn existing;\n\t}\n\treturn value;\n}\n\n/**\n * Does not change map.\n * If (key1, key2) is not in map, returns value.\n * If (key1, key2) is in map, return its entry.\n */\nexport function getOrDefaultInNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n\tvalue: Value,\n): Value {\n\tconst existing = tryGetFromNestedMap(map, key1, key2);\n\tif (existing !== undefined) {\n\t\treturn existing;\n\t}\n\treturn value;\n}\n\n/**\n * Removes the value at (key1, key2) from the map.\n *\n * @returns true iff found.\n */\nexport function deleteFromNestedMap<Key1, Key2, Value>(\n\tmap: NestedMap<Key1, Key2, Value>,\n\tkey1: Key1,\n\tkey2: Key2,\n): boolean {\n\tconst innerMap = map.get(key1);\n\tif (innerMap === undefined) {\n\t\treturn false;\n\t}\n\tconst deleted = innerMap.delete(key2);\n\tif (innerMap.size === 0) {\n\t\tmap.delete(key1);\n\t}\n\treturn deleted;\n}\n\n/**\n * Converts a nested map to a flat list of triplets.\n */\nexport function nestedMapToFlatList<Key1, Key2, Value>(\n\tmap: ReadonlyNestedMap<Key1, Key2, Value>,\n): [Key1, Key2, Value][] {\n\tconst list: [Key1, Key2, Value][] = [];\n\tmap.forEach((innerMap, key1) => {\n\t\tinnerMap.forEach((val, key2) => {\n\t\t\tlist.push([key1, key2, val]);\n\t\t});\n\t});\n\treturn list;\n}\n\n/**\n * Builds a nested map from a flat list of triplets.\n */\nexport function nestedMapFromFlatList<Key1, Key2, Value>(\n\tlist: readonly (readonly [Key1, Key2, Value])[],\n): NestedMap<Key1, Key2, Value> {\n\tconst map = new Map<Key1, Map<Key2, Value>>();\n\tfor (const [key1, key2, val] of list) {\n\t\tgetOrAddInMap(map, key1, new Map<Key2, Value>()).set(key2, val);\n\t}\n\treturn map;\n}\n\nexport function forEachInNestedMap<Key1, Key2, Value>(\n\tmap: ReadonlyNestedMap<Key1, Key2, Value>,\n\tdelegate: (value: Value, key1: Key1, key2: Key2) => void,\n): void {\n\tmap.forEach((innerMap, keyFirst) => {\n\t\tinnerMap.forEach((val, keySecond) => {\n\t\t\tdelegate(val, keyFirst, keySecond);\n\t\t});\n\t});\n}\n\n/**\n * Maps the `input` map values using the provided `delegate`.\n *\n * @param input - The `NestedMap` whose contents are being mapped.\n * @param delegate - The delegate to use for mapping values,\n * @returns A new `NestedMap` with the same keys as `input`, but with the values produced by `delegate`.\n */\nexport function mapNestedMap<Key1, Key2, ValueIn, ValueOut = ValueIn>(\n\tinput: ReadonlyNestedMap<Key1, Key2, ValueIn>,\n\tdelegate: (value: ValueIn, key1: Key1, key2: Key2) => ValueOut,\n): NestedMap<Key1, Key2, ValueOut> {\n\tconst output = new Map<Key1, Map<Key2, ValueOut>>();\n\tinput.forEach((inputInnerMap, keyFirst) => {\n\t\tconst outputInnerMap = new Map<Key2, ValueOut>();\n\t\tinputInnerMap.forEach((val, keySecond) => {\n\t\t\tconst mappedValue = delegate(val, keyFirst, keySecond);\n\t\t\toutputInnerMap.set(keySecond, mappedValue);\n\t\t});\n\t\toutput.set(keyFirst, outputInnerMap);\n\t});\n\treturn output;\n}\n\n/**\n * Map with two keys; same semantics as NestedMap, but maintains a size count for the entire collection.\n * Note: undefined is not supported as a value, and will cause incorrect behavior.\n */\nexport class SizedNestedMap<Key1, Key2, Value> {\n\tprivate readonly nestedMap: NestedMap<Key1, Key2, Value> = new Map();\n\tprivate count = 0;\n\n\t/**\n\t * Returns the total number of elements in this nested map.\n\t */\n\tpublic get size(): number {\n\t\treturn this.count;\n\t}\n\n\t/**\n\t * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is\n\t * returned.\n\t */\n\tpublic tryGet(key1: Key1, key2: Key2): Value | undefined {\n\t\treturn tryGetFromNestedMap(this.nestedMap, key1, key2);\n\t}\n\n\t/**\n\t * Does not change map.\n\t * If (key1, key2) is not in map, returns value.\n\t * If (key1, key2) is in map, return its entry.\n\t */\n\tpublic getOrDefault(key1: Key1, key2: Key2, value: Value): Value {\n\t\treturn getOrDefaultInNestedMap(this.nestedMap, key1, key2, value);\n\t}\n\n\t/**\n\t * If (key1, key2) already has a value in the map, it is returned, otherwise value is added under (key1, key2) and undefined is\n\t * returned.\n\t */\n\tpublic tryAdd(key1: Key1, key2: Key2, value: Value): Value | undefined {\n\t\tconst currentVal = tryAddToNestedMap(this.nestedMap, key1, key2, value);\n\t\tif (currentVal === undefined) {\n\t\t\tthis.count++;\n\t\t}\n\t\treturn currentVal;\n\t}\n\n\t/**\n\t * Sets the value at (key1, key2) in map to value.\n\t * If there already is a value for (key1, key2), it is replaced with the provided one.\n\t */\n\tpublic set(key1: Key1, key2: Key2, value: Value): void {\n\t\tif (this.tryAdd(key1, key2, value) !== undefined) {\n\t\t\tsetInNestedMap(this.nestedMap, key1, key2, value);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the value at (key1, key2) from the map.\n\t * Returns true iff found.\n\t */\n\tpublic delete(key1: Key1, key2: Key2): boolean {\n\t\tconst deleted = deleteFromNestedMap(this.nestedMap, key1, key2);\n\t\tif (deleted) {\n\t\t\tthis.count--;\n\t\t}\n\t\treturn deleted;\n\t}\n\n\t/**\n\t * Runs the supplied delegate for every (value, key1, key2).\n\t */\n\tpublic forEach(delegate: (value: Value, key1: Key1, key2: Key2) => void): void {\n\t\tforEachInNestedMap(this.nestedMap, delegate);\n\t}\n\n\t/**\n\t * Clears the map.\n\t */\n\tpublic clear(): void {\n\t\tthis.count = 0;\n\t\tthis.nestedMap.clear();\n\t}\n\n\tpublic values(): IterableIterator<Value> {\n\t\treturn (\n\t\t\tArray.from(this.nestedMap.values()).flatMap((innerMap) => innerMap.values())[0] ?? oob()\n\t\t);\n\t}\n\n\tpublic [Symbol.iterator](): IterableIterator<[Key1, Map<Key2, Value>]> {\n\t\treturn this.nestedMap[Symbol.iterator]();\n\t}\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * An object which counts the number of users / references to it.
7
7
  * @remarks
8
- * This implements the [Reference counting](https://en.wikipedia.org/wiki/Reference_counting) pattern.
8
+ * This implements the {@link https://en.wikipedia.org/wiki/Reference_counting | Reference counting} pattern.
9
9
  * Getting the reference count correct is difficult in TypeScript and great care must be used.
10
10
  * Because of this, this interface should not be used in the public API.
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"referenceCounting.js","sourceRoot":"","sources":["../../src/util/referenceCounting.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAgC7D;;GAEG;AACH,MAAM,OAAgB,oBAAoB;IACzC,YAA8B,WAAmB,CAAC;QAApB,aAAQ,GAAR,QAAQ,CAAY;IAAG,CAAC;IAE/C,cAAc,CAAC,KAAK,GAAG,CAAC;QAC9B,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IACxB,CAAC;IAEM,gBAAgB,CAAC,KAAK,GAAG,CAAC;QAChC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC1B,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC5B,CAAC;CAMD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\n/**\n * An object which counts the number of users / references to it.\n * @remarks\n * This implements the [Reference counting](https://en.wikipedia.org/wiki/Reference_counting) pattern.\n * Getting the reference count correct is difficult in TypeScript and great care must be used.\n * Because of this, this interface should not be used in the public API.\n */\nexport interface ReferenceCounted {\n\t/**\n\t * Called to increase the reference count tracked by this object.\n\t * @remarks\n\t * When a user of this object allows something else to use it,\n\t * this should be called.\n\t */\n\treferenceAdded(): void;\n\t/**\n\t * Called to decrease the reference count tracked by this object.\n\t * @remarks\n\t * When a user of this object will no longer use it, this should be called.\n\t */\n\treferenceRemoved(): void;\n\n\t/**\n\t * @returns true if mutating this object may impact other users of it.\n\t *\n\t * Implementations can return true if the refcount is 1 OR the content is logically immutable.\n\t */\n\tisShared(): boolean;\n}\n\n/**\n * Base class to assist with implementing ReferenceCounted.\n */\nexport abstract class ReferenceCountedBase implements ReferenceCounted {\n\tprotected constructor(private refCount: number = 1) {}\n\n\tpublic referenceAdded(count = 1): void {\n\t\tthis.refCount += count;\n\t}\n\n\tpublic referenceRemoved(count = 1): void {\n\t\tthis.refCount -= count;\n\t\tassert(this.refCount >= 0, 0x4c4 /* Negative ref count */);\n\t\tif (this.refCount === 0) {\n\t\t\tthis.onUnreferenced();\n\t\t}\n\t}\n\n\tpublic isShared(): boolean {\n\t\treturn this.refCount > 1;\n\t}\n\n\tpublic isUnreferenced(): boolean {\n\t\treturn this.refCount === 0;\n\t}\n\n\t/**\n\t * Called when refcount reaches 0.\n\t */\n\tprotected abstract onUnreferenced(): void;\n}\n"]}
1
+ {"version":3,"file":"referenceCounting.js","sourceRoot":"","sources":["../../src/util/referenceCounting.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAgC7D;;GAEG;AACH,MAAM,OAAgB,oBAAoB;IACzC,YAA8B,WAAmB,CAAC;QAApB,aAAQ,GAAR,QAAQ,CAAY;IAAG,CAAC;IAE/C,cAAc,CAAC,KAAK,GAAG,CAAC;QAC9B,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IACxB,CAAC;IAEM,gBAAgB,CAAC,KAAK,GAAG,CAAC;QAChC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC1B,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC5B,CAAC;CAMD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\n/**\n * An object which counts the number of users / references to it.\n * @remarks\n * This implements the {@link https://en.wikipedia.org/wiki/Reference_counting | Reference counting} pattern.\n * Getting the reference count correct is difficult in TypeScript and great care must be used.\n * Because of this, this interface should not be used in the public API.\n */\nexport interface ReferenceCounted {\n\t/**\n\t * Called to increase the reference count tracked by this object.\n\t * @remarks\n\t * When a user of this object allows something else to use it,\n\t * this should be called.\n\t */\n\treferenceAdded(): void;\n\t/**\n\t * Called to decrease the reference count tracked by this object.\n\t * @remarks\n\t * When a user of this object will no longer use it, this should be called.\n\t */\n\treferenceRemoved(): void;\n\n\t/**\n\t * @returns true if mutating this object may impact other users of it.\n\t *\n\t * Implementations can return true if the refcount is 1 OR the content is logically immutable.\n\t */\n\tisShared(): boolean;\n}\n\n/**\n * Base class to assist with implementing ReferenceCounted.\n */\nexport abstract class ReferenceCountedBase implements ReferenceCounted {\n\tprotected constructor(private refCount: number = 1) {}\n\n\tpublic referenceAdded(count = 1): void {\n\t\tthis.refCount += count;\n\t}\n\n\tpublic referenceRemoved(count = 1): void {\n\t\tthis.refCount -= count;\n\t\tassert(this.refCount >= 0, 0x4c4 /* Negative ref count */);\n\t\tif (this.refCount === 0) {\n\t\t\tthis.onUnreferenced();\n\t\t}\n\t}\n\n\tpublic isShared(): boolean {\n\t\treturn this.refCount > 1;\n\t}\n\n\tpublic isUnreferenced(): boolean {\n\t\treturn this.refCount === 0;\n\t}\n\n\t/**\n\t * Called when refcount reaches 0.\n\t */\n\tprotected abstract onUnreferenced(): void;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/tree",
3
- "version": "2.70.0-361092",
3
+ "version": "2.70.0-361788",
4
4
  "description": "Distributed tree",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -101,17 +101,17 @@
101
101
  "temp-directory": "nyc/.nyc_output"
102
102
  },
103
103
  "dependencies": {
104
- "@fluid-internal/client-utils": "2.70.0-361092",
105
- "@fluidframework/container-runtime": "2.70.0-361092",
106
- "@fluidframework/core-interfaces": "2.70.0-361092",
107
- "@fluidframework/core-utils": "2.70.0-361092",
108
- "@fluidframework/datastore-definitions": "2.70.0-361092",
109
- "@fluidframework/driver-definitions": "2.70.0-361092",
110
- "@fluidframework/id-compressor": "2.70.0-361092",
111
- "@fluidframework/runtime-definitions": "2.70.0-361092",
112
- "@fluidframework/runtime-utils": "2.70.0-361092",
113
- "@fluidframework/shared-object-base": "2.70.0-361092",
114
- "@fluidframework/telemetry-utils": "2.70.0-361092",
104
+ "@fluid-internal/client-utils": "2.70.0-361788",
105
+ "@fluidframework/container-runtime": "2.70.0-361788",
106
+ "@fluidframework/core-interfaces": "2.70.0-361788",
107
+ "@fluidframework/core-utils": "2.70.0-361788",
108
+ "@fluidframework/datastore-definitions": "2.70.0-361788",
109
+ "@fluidframework/driver-definitions": "2.70.0-361788",
110
+ "@fluidframework/id-compressor": "2.70.0-361788",
111
+ "@fluidframework/runtime-definitions": "2.70.0-361788",
112
+ "@fluidframework/runtime-utils": "2.70.0-361788",
113
+ "@fluidframework/shared-object-base": "2.70.0-361788",
114
+ "@fluidframework/telemetry-utils": "2.70.0-361788",
115
115
  "@sinclair/typebox": "^0.34.13",
116
116
  "@tylerbu/sorted-btree-es6": "^1.8.0",
117
117
  "@types/ungap__structured-clone": "^1.2.0",
@@ -122,19 +122,19 @@
122
122
  "devDependencies": {
123
123
  "@arethetypeswrong/cli": "^0.17.1",
124
124
  "@biomejs/biome": "~1.9.3",
125
- "@fluid-internal/mocha-test-setup": "2.70.0-361092",
126
- "@fluid-private/stochastic-test-utils": "2.70.0-361092",
127
- "@fluid-private/test-dds-utils": "2.70.0-361092",
128
- "@fluid-private/test-drivers": "2.70.0-361092",
125
+ "@fluid-internal/mocha-test-setup": "2.70.0-361788",
126
+ "@fluid-private/stochastic-test-utils": "2.70.0-361788",
127
+ "@fluid-private/test-dds-utils": "2.70.0-361788",
128
+ "@fluid-private/test-drivers": "2.70.0-361788",
129
129
  "@fluid-tools/benchmark": "^0.51.0",
130
130
  "@fluid-tools/build-cli": "^0.58.3",
131
131
  "@fluidframework/build-common": "^2.0.3",
132
132
  "@fluidframework/build-tools": "^0.58.3",
133
- "@fluidframework/container-definitions": "2.70.0-361092",
134
- "@fluidframework/container-loader": "2.70.0-361092",
133
+ "@fluidframework/container-definitions": "2.70.0-361788",
134
+ "@fluidframework/container-loader": "2.70.0-361788",
135
135
  "@fluidframework/eslint-config-fluid": "^6.1.0",
136
- "@fluidframework/test-runtime-utils": "2.70.0-361092",
137
- "@fluidframework/test-utils": "2.70.0-361092",
136
+ "@fluidframework/test-runtime-utils": "2.70.0-361788",
137
+ "@fluidframework/test-utils": "2.70.0-361788",
138
138
  "@fluidframework/tree-previous": "npm:@fluidframework/tree@2.63.0",
139
139
  "@microsoft/api-extractor": "7.52.11",
140
140
  "@types/diff": "^3.5.1",
@@ -147,7 +147,7 @@
147
147
  "concurrently": "^8.2.1",
148
148
  "copyfiles": "^2.4.1",
149
149
  "cross-env": "^7.0.3",
150
- "dependency-cruiser": "^14.1.0",
150
+ "dependency-cruiser": "^17.1.0",
151
151
  "diff": "^3.5.0",
152
152
  "easy-table": "^1.1.1",
153
153
  "eslint": "~8.57.1",
package/src/api.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  import {
7
7
  type TreeView,
8
8
  type TreeViewAlpha,
9
+ type TreeViewBeta,
9
10
  type ImplicitFieldSchema,
10
11
  // eslint-disable-next-line import/no-deprecated
11
12
  asTreeViewAlpha,
@@ -28,3 +29,13 @@ export function asAlpha<TSchema extends ImplicitFieldSchema>(
28
29
  // eslint-disable-next-line import/no-deprecated
29
30
  return asTreeViewAlpha(view);
30
31
  }
32
+
33
+ /**
34
+ * Retrieve the {@link TreeViewBeta | beta API} for a {@link TreeView}.
35
+ * @beta
36
+ */
37
+ export function asBeta<TSchema extends ImplicitFieldSchema>(
38
+ view: TreeView<TSchema>,
39
+ ): TreeViewBeta<TSchema> {
40
+ return view as TreeViewBeta<TSchema>;
41
+ }
@@ -164,7 +164,7 @@ export interface CodecWriteOptions extends ICodecOptions {
164
164
  * appropriate one, but depending on API layering this might be less ergonomic.
165
165
  * - Context for the object currently being encoded, which might enable more efficient encoding. When used in this fashion, the codec author
166
166
  * should be careful to include the context somewhere in the encoded data such that decoding can correctly round-trip.
167
- * For example, a composed set of codecs could implement a form of [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder)
167
+ * For example, a composed set of codecs could implement a form of {@link https://en.wikipedia.org/wiki/Dictionary_coder | dictionary coding}
168
168
  * using a context map which was created by the top-level codec and passed to the inner codecs.
169
169
  * This pattern is used:
170
170
  * - To avoid repeatedly encoding session ids on commits (only recording it once at the top level)
@@ -227,14 +227,14 @@ export interface IMultiFormatCodec<
227
227
  * allows avoiding some duplicate work at encode/decode time, since the vast majority of document usage will not
228
228
  * involve mixed format versions.
229
229
  *
230
- * @privateRemarks - This interface currently assumes all codecs in a family require the same encode/decode context,
230
+ * @privateRemarks This interface currently assumes all codecs in a family require the same encode/decode context,
231
231
  * which isn't necessarily true.
232
232
  * This may need to be relaxed in the future.
233
233
  */
234
234
  export interface ICodecFamily<TDecoded, TContext = void> {
235
235
  /**
236
236
  * @returns a codec that can be used to encode and decode data in the specified format.
237
- * @throws - if the format version is not supported by this family.
237
+ * @throws if the format version is not supported by this family.
238
238
  * @remarks Implementations should typically emit telemetry (either indirectly by throwing a well-known error with
239
239
  * logged properties or directly using some logger) when a format version is requested that is not supported.
240
240
  * This ensures that applications can diagnose compatibility issues.
@@ -84,15 +84,14 @@ export interface IForestSubscription {
84
84
  clone(schema: TreeStoredSchemaSubscription, anchors: AnchorSet): IEditableForest;
85
85
 
86
86
  /**
87
- * Generate a TreeChunk for the content in the given field cursor.
87
+ * Generate a TreeChunk[] for the current field (and its children) of cursor.
88
88
  * This can be used to chunk data that is then inserted into the forest.
89
89
  *
90
90
  * @remarks
91
- * Like {@link chunkField}, but forces the results into a single TreeChunk.
92
- * While any TreeChunk is compatible with any forest, this method creates one optimized for this specific forest.
91
+ * Similar to {@link chunkField} but it creates chunks optimized for this specific forest by using its compression policy.
93
92
  * The provided data must be compatible with the forest's current schema.
94
93
  */
95
- chunkField(cursor: ITreeCursorSynchronous): TreeChunk;
94
+ chunkField(cursor: ITreeCursorSynchronous): TreeChunk[];
96
95
 
97
96
  /**
98
97
  * Allocates a cursor in the "cleared" state.
@@ -12,7 +12,7 @@ import type { RevisionTag } from "./types.js";
12
12
  *
13
13
  * This interface is used to provide rebase policy to `Rebaser`.
14
14
  *
15
- * The implementation must ensure TChangeset forms a [group](https://en.wikipedia.org/wiki/Group_(mathematics)) where:
15
+ * The implementation must ensure TChangeset forms a {@link https://en.wikipedia.org/wiki/Group_(mathematics | group}) where:
16
16
  * - `compose([])` is the identity element.
17
17
  * - associativity is defined as `compose([...a, ...b])` is equal to
18
18
  * `compose([compose(a), compose(b)])` for all `a` and `b`.
@@ -293,7 +293,10 @@ export class DetachedFieldIndex {
293
293
  root: brand<ForestRootId>(root + i),
294
294
  latestRelevantRevision: revision,
295
295
  });
296
- setInNestedMap(this.latestRelevantRevisionToFields, revision, root, nodeId);
296
+ setInNestedMap(this.latestRelevantRevisionToFields, revision, root + i, {
297
+ major: nodeId.major,
298
+ minor: nodeId.minor + i,
299
+ });
297
300
  }
298
301
  }
299
302
  return root;
@@ -197,6 +197,15 @@ export function chunkFieldSingle(
197
197
  policy: ChunkCompressor,
198
198
  ): TreeChunk {
199
199
  const chunks = chunkField(cursor, policy);
200
+ return combineChunks(chunks);
201
+ }
202
+
203
+ /**
204
+ * Create a single TreeChunk from an array of TreeChunks.
205
+ * @remarks
206
+ * This takes ownership of the provided TreeChunk references, and returns an owned referenced.
207
+ */
208
+ export function combineChunks(chunks: TreeChunk[]): TreeChunk {
200
209
  if (chunks.length === 1) {
201
210
  return chunks[0] ?? oob();
202
211
  }
@@ -44,7 +44,7 @@ import {
44
44
  } from "../../util/index.js";
45
45
 
46
46
  import { BasicChunk, BasicChunkCursor, type SiblingsOrKey } from "./basicChunk.js";
47
- import { type IChunker, basicChunkTree, chunkFieldSingle, chunkTree } from "./chunkTree.js";
47
+ import { type IChunker, basicChunkTree, chunkField, chunkTree } from "./chunkTree.js";
48
48
 
49
49
  function makeRoot(): BasicChunk {
50
50
  return new BasicChunk(aboveRootPlaceholder, new Map());
@@ -90,8 +90,8 @@ export class ChunkedForest implements IEditableForest {
90
90
  return new ChunkedForest(this.roots, schema, this.chunker.clone(schema), anchors);
91
91
  }
92
92
 
93
- public chunkField(cursor: ITreeCursorSynchronous): TreeChunk {
94
- return chunkFieldSingle(cursor, { idCompressor: this.idCompressor, policy: this.chunker });
93
+ public chunkField(cursor: ITreeCursorSynchronous): TreeChunk[] {
94
+ return chunkField(cursor, { idCompressor: this.idCompressor, policy: this.chunker });
95
95
  }
96
96
 
97
97
  public forgetAnchor(anchor: Anchor): void {
@@ -36,7 +36,7 @@ import {
36
36
  SpecialField,
37
37
  version,
38
38
  } from "./format.js";
39
- import type { ChunkReferenceId, IncrementalEncoder } from "./codecs.js";
39
+ import type { IncrementalEncoder } from "./codecs.js";
40
40
 
41
41
  /**
42
42
  * Encode data from `FieldBatch` into an `EncodedFieldBatch`.
@@ -223,8 +223,8 @@ export const anyNodeEncoder: NodeEncoder = {
223
223
  outputBuffer: BufferFormat,
224
224
  ): void {
225
225
  // TODO: Fast path uniform chunk content.
226
- const shape = context.nodeEncoderFromSchema(cursor.type);
227
- AnyShape.encodeNode(cursor, context, outputBuffer, shape);
226
+ const nodeEncoder = context.nodeEncoderFromSchema(cursor.type);
227
+ AnyShape.encodeNode(cursor, context, outputBuffer, nodeEncoder);
228
228
  },
229
229
 
230
230
  shape: AnyShape.instance,
@@ -350,7 +350,7 @@ export class InlineArrayEncoder
350
350
  }
351
351
 
352
352
  /**
353
- * Encodes the shape for a nested array as {@link EncodedNestedArray} shape.
353
+ * Encodes the shape for a nested array as {@link EncodedNestedArrayShape} shape.
354
354
  */
355
355
  export class NestedArrayShape extends ShapeGeneric<EncodedChunkShape> {
356
356
  /**
@@ -420,30 +420,9 @@ export class NestedArrayEncoder implements FieldEncoder {
420
420
  }
421
421
 
422
422
  /**
423
- * Encodes a chunk with the {@link EncodedIncrementalChunkShape} shape.
424
- * This chunks will be encoded separately, i.e., the contents of the chunk will not be part of the main buffer.
425
- * A reference to the chunk will be stored in the main buffer as an {@link ChunkReferenceId}.
423
+ * Encodes the shape for an incremental chunk as {@link EncodedIncrementalChunkShape} shape.
426
424
  */
427
425
  export class IncrementalChunkShape extends ShapeGeneric<EncodedChunkShape> {
428
- /**
429
- * Encodes all the nodes in the chunk at the cursor position using `InlineArrayShape`.
430
- */
431
- public static encodeChunk(chunk: TreeChunk, context: EncoderContext): BufferFormat {
432
- const chunkOutputBuffer: BufferFormat = [];
433
- const nodesEncoder = asNodesEncoder(anyNodeEncoder);
434
- const chunkCursor = chunk.cursor();
435
- chunkCursor.firstNode();
436
- const chunkLength = chunkCursor.chunkLength;
437
- for (let index = 0; index < chunkLength; index++) {
438
- nodesEncoder.encodeNodes(chunkCursor, context, chunkOutputBuffer);
439
- }
440
- assert(
441
- chunkCursor.mode === CursorLocationType.Fields,
442
- 0xc29 /* should return to fields mode when finished encoding */,
443
- );
444
- return chunkOutputBuffer;
445
- }
446
-
447
426
  public encodeShape(
448
427
  identifiers: DeduplicationTable<string>,
449
428
  shapes: DeduplicationTable<Shape>,
@@ -464,9 +443,10 @@ export class IncrementalChunkShape extends ShapeGeneric<EncodedChunkShape> {
464
443
  }
465
444
 
466
445
  /**
467
- * Encodes an incremental field whose chunks are encoded separately and referenced by their {@link ChunkReferenceId}.
468
- * The shape of the content of this field is {@link NestedShape} where the items in the array are
469
- * the {@link ChunkReferenceId}s of the encoded chunks.
446
+ * Encodes an incremental field whose tree chunks are encoded separately and referenced by their {@link ChunkReferenceId}.
447
+ * The shape of the content of this field is {@link NestedArrayShape}.
448
+ * The inner items of the array have shape {@link IncrementalChunkShape} and are {@link ChunkReferenceId}s
449
+ * of the encoded chunks.
470
450
  */
471
451
  export const incrementalFieldEncoder: FieldEncoder = {
472
452
  encodeField(
@@ -475,12 +455,13 @@ export const incrementalFieldEncoder: FieldEncoder = {
475
455
  outputBuffer: BufferFormat,
476
456
  ): void {
477
457
  assert(
478
- context.shouldEncodeIncrementally,
479
- 0xc2a /* incremental encoding must be enabled to use IncrementalFieldShape */,
458
+ context.incrementalEncoder !== undefined,
459
+ "incremental encoder must be defined to use incrementalFieldEncoder",
480
460
  );
481
461
 
482
- const chunkReferenceIds = context.encodeIncrementalField(cursor, (chunk: TreeChunk) =>
483
- IncrementalChunkShape.encodeChunk(chunk, context),
462
+ const chunkReferenceIds = context.incrementalEncoder.encodeIncrementalField(
463
+ cursor,
464
+ (chunk: TreeChunk) => compressedEncode([chunk.cursor()], context),
484
465
  );
485
466
  outputBuffer.push(chunkReferenceIds);
486
467
  },
@@ -540,7 +521,12 @@ export class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
540
521
  private readonly fieldEncoderFromPolicy: FieldEncoderPolicy,
541
522
  public readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
542
523
  public readonly idCompressor: IIdCompressor,
543
- private readonly incrementalEncoder: IncrementalEncoder | undefined,
524
+ /**
525
+ * To be used to encode incremental chunks, if any.
526
+ * @remarks
527
+ * See {@link IncrementalEncoder} for more information.
528
+ */
529
+ public readonly incrementalEncoder: IncrementalEncoder | undefined,
544
530
  ) {}
545
531
 
546
532
  public nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder {
@@ -556,30 +542,6 @@ export class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
556
542
  public nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder {
557
543
  return getOrCreate(this.nestedArrayEncoders, inner, () => new NestedArrayEncoder(inner));
558
544
  }
559
-
560
- public get shouldEncodeIncrementally(): boolean {
561
- return this.incrementalEncoder !== undefined;
562
- }
563
-
564
- /**
565
- * {@link IncrementalEncoder.encodeIncrementalField}
566
- */
567
- public encodeIncrementalField(
568
- cursor: ITreeCursorSynchronous,
569
- encoder: (chunk: TreeChunk) => BufferFormat,
570
- ): ChunkReferenceId[] {
571
- assert(
572
- this.incrementalEncoder !== undefined,
573
- 0xc2b /* incremental encoding must be enabled */,
574
- );
575
- // Encoder for the chunk that encodes its data using the provided encoder function and
576
- // updates the encoded data for shapes and identifiers.
577
- const chunkEncoder = (chunk: TreeChunk): EncodedFieldBatch => {
578
- const chunkOutputBuffer = encoder(chunk);
579
- return updateShapesAndIdentifiersEncoding(version, [chunkOutputBuffer]);
580
- };
581
- return this.incrementalEncoder.encodeIncrementalField(cursor, chunkEncoder);
582
- }
583
545
  }
584
546
 
585
547
  export interface NodeEncodeBuilder {
@@ -12,6 +12,7 @@ export {
12
12
  type IChunker,
13
13
  chunkFieldSingle,
14
14
  chunkField,
15
+ combineChunks,
15
16
  } from "./chunkTree.js";
16
17
  export { buildChunkedForest } from "./chunkedForest.js";
17
18
  export {
@@ -53,6 +53,7 @@ import {
53
53
  import { LazyEntity } from "./lazyEntity.js";
54
54
  import { type LazyTreeNode, getOrCreateHydratedFlexTreeNode } from "./lazyNode.js";
55
55
  import { indexForAt, treeStatusFromAnchorCache } from "./utilities.js";
56
+ import { combineChunks } from "../chunked-forest/index.js";
56
57
 
57
58
  /**
58
59
  * Reuse fields.
@@ -247,7 +248,8 @@ export abstract class LazyField extends LazyEntity<FieldAnchor> implements FlexT
247
248
  protected getEditor(): IDefaultEditBuilder<ITreeCursorSynchronous> {
248
249
  return new MappedEditBuilder(
249
250
  this.context.checkout.editor,
250
- (cursor: ITreeCursorSynchronous) => this.context.checkout.forest.chunkField(cursor),
251
+ (cursor: ITreeCursorSynchronous) =>
252
+ combineChunks(this.context.checkout.forest.chunkField(cursor)),
251
253
  );
252
254
  }
253
255
  }
@@ -31,7 +31,7 @@ export function treeStatusFromDetachedField(detachedField: DetachedField): TreeS
31
31
  *
32
32
  * @param anchors - the {@link AnchorSet} to compare your anchorNode cache to.
33
33
  * @param anchorNode - the {@link AnchorNode} to get the {@link TreeStatus} of.
34
- * @returns - the {@link TreeStatus} of the anchorNode provided.
34
+ * @returns the {@link TreeStatus} of the anchorNode provided.
35
35
  */
36
36
  export function treeStatusFromAnchorCache(anchorNode: AnchorNode): TreeStatus {
37
37
  const cache = anchorNode.slots.get(detachedFieldSlot);
@@ -288,7 +288,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
288
288
 
289
289
  public constructor(
290
290
  private readonly enableIncrementalSummary: boolean,
291
- private readonly getChunkAtCursor: (cursor: ITreeCursorSynchronous) => TreeChunk,
291
+ private readonly getChunkAtCursor: (cursor: ITreeCursorSynchronous) => TreeChunk[],
292
292
  public readonly shouldEncodeIncrementally: IncrementalEncodingPolicy,
293
293
  private readonly initialSequenceNumber: number,
294
294
  ) {}
@@ -392,80 +392,74 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
392
392
  // Validate that a summary is currently being tracked and that the tracked summary properties are defined.
393
393
  validateTrackingSummary(this.forestSummaryState, this.trackedSummaryProperties);
394
394
 
395
- if (cursor.getFieldLength() === 0) {
396
- return [];
397
- }
398
-
399
- let chunkReferenceId: ChunkReferenceId;
400
- let chunkProperties: ChunkSummaryProperties;
395
+ const chunkReferenceIds: ChunkReferenceId[] = [];
396
+ const chunks = this.getChunkAtCursor(cursor);
397
+ for (const chunk of chunks) {
398
+ let chunkProperties: ChunkSummaryProperties;
399
+
400
+ // Try and get the properties of the chunk from the latest successful summary.
401
+ // If it exists and the summary is not a full tree, use the properties to generate a summary handle.
402
+ // If it does not exist, encode the chunk and generate new properties for it.
403
+ const previousChunkProperties = tryGetFromNestedMap(
404
+ this.chunkTrackingPropertiesMap,
405
+ this.latestSummarySequenceNumber,
406
+ chunk,
407
+ );
408
+ if (previousChunkProperties !== undefined && !this.trackedSummaryProperties.fullTree) {
409
+ chunkProperties = previousChunkProperties;
410
+ this.trackedSummaryProperties.parentSummaryBuilder.addHandle(
411
+ `${chunkProperties.referenceId}`,
412
+ SummaryType.Tree,
413
+ `${this.trackedSummaryProperties.latestSummaryBasePath}/${chunkProperties.summaryPath}`,
414
+ );
415
+ } else {
416
+ // Generate a new reference ID for the chunk.
417
+ const newReferenceId: ChunkReferenceId = brand(this.nextReferenceId++);
418
+
419
+ // Add the reference ID of this chunk to the chunk summary path and use the path as the summary path
420
+ // for the chunk in its summary properties.
421
+ // This is done before encoding the chunk so that the summary path is updated correctly when encoding
422
+ // any incremental chunks that are under this chunk.
423
+ this.trackedSummaryProperties.chunkSummaryPath.push(newReferenceId);
424
+
425
+ chunkProperties = {
426
+ referenceId: newReferenceId,
427
+ summaryPath: this.trackedSummaryProperties.chunkSummaryPath.join("/"),
428
+ };
429
+
430
+ const parentSummaryBuilder = this.trackedSummaryProperties.parentSummaryBuilder;
431
+ // Create a new summary builder for this chunk to build its summary tree which will be stored in the
432
+ // parent's summary tree under its reference ID.
433
+ // Before encoding the chunk, set the parent summary builder to this chunk's summary builder so that
434
+ // any incremental chunks in the subtree of this chunk will use that as their parent summary builder.
435
+ const chunkSummaryBuilder = new SummaryTreeBuilder();
436
+ this.trackedSummaryProperties.parentSummaryBuilder = chunkSummaryBuilder;
437
+ chunkSummaryBuilder.addBlob(
438
+ chunkContentsBlobKey,
439
+ this.trackedSummaryProperties.stringify(chunkEncoder(chunk)),
440
+ );
401
441
 
402
- // An additional ref-count must be added to these chunks representing a reference from the summary tree to the chunk.
403
- // This will ensure that the blob's content never change and thus the reference stays accurate: instead of modifying it,
404
- // a copy will be created without the blob reference.
405
- // The "getChunkAtCursor" adds this additional ref-count.
406
- const chunk = this.getChunkAtCursor(cursor);
442
+ // Add this chunk's summary tree to the parent's summary tree. The summary tree contains its encoded
443
+ // contents and the summary trees of any incremental chunks under it.
444
+ parentSummaryBuilder.addWithStats(
445
+ `${newReferenceId}`,
446
+ chunkSummaryBuilder.getSummaryTree(),
447
+ );
407
448
 
408
- // Try and get the properties of the chunk from the latest successful summary.
409
- // If it exists and the summary is not a full tree, use the properties to generate a summary handle.
410
- // If it does not exist, encode the chunk and generate new properties for it.
411
- const previousChunkProperties = tryGetFromNestedMap(
412
- this.chunkTrackingPropertiesMap,
413
- this.latestSummarySequenceNumber,
414
- chunk,
415
- );
416
- if (previousChunkProperties !== undefined && !this.trackedSummaryProperties.fullTree) {
417
- chunkProperties = previousChunkProperties;
418
- chunkReferenceId = previousChunkProperties.referenceId;
419
- this.trackedSummaryProperties.parentSummaryBuilder.addHandle(
420
- `${chunkReferenceId}`,
421
- SummaryType.Tree,
422
- `${this.trackedSummaryProperties.latestSummaryBasePath}/${previousChunkProperties.summaryPath}`,
423
- );
424
- } else {
425
- // Generate a new reference ID for the chunk.
426
- chunkReferenceId = brand(this.nextReferenceId++);
427
- // Add the reference ID of this chunk to the chunk summary path and use the path as the summary path
428
- // for the chunk in its summary properties.
429
- // This is done before encoding the chunk so that the summary path is updated correctly when encoding
430
- // any incremental chunks that are under this chunk.
431
- this.trackedSummaryProperties.chunkSummaryPath.push(chunkReferenceId);
432
-
433
- chunkProperties = {
434
- referenceId: chunkReferenceId,
435
- summaryPath: this.trackedSummaryProperties.chunkSummaryPath.join("/"),
436
- };
437
-
438
- const parentSummaryBuilder = this.trackedSummaryProperties.parentSummaryBuilder;
439
- // Create a new summary builder for this chunk to build its summary tree which will be stored in the
440
- // parent's summary tree under its reference ID.
441
- // Before encoding the chunk, set the parent summary builder to this chunk's summary builder so that
442
- // any incremental chunks in the subtree of this chunk will use that as their parent summary builder.
443
- const chunkSummaryBuilder = new SummaryTreeBuilder();
444
- this.trackedSummaryProperties.parentSummaryBuilder = chunkSummaryBuilder;
445
- chunkSummaryBuilder.addBlob(
446
- chunkContentsBlobKey,
447
- this.trackedSummaryProperties.stringify(chunkEncoder(chunk)),
448
- );
449
+ // Restore the parent summary builder and chunk summary path.
450
+ this.trackedSummaryProperties.parentSummaryBuilder = parentSummaryBuilder;
451
+ this.trackedSummaryProperties.chunkSummaryPath.pop();
452
+ }
449
453
 
450
- // Add this chunk's summary tree to the parent's summary tree. The summary tree contains its encoded
451
- // contents and the summary trees of any incremental chunks under it.
452
- parentSummaryBuilder.addWithStats(
453
- `${chunkReferenceId}`,
454
- chunkSummaryBuilder.getSummaryTree(),
454
+ setInNestedMap(
455
+ this.chunkTrackingPropertiesMap,
456
+ this.trackedSummaryProperties.summarySequenceNumber,
457
+ chunk,
458
+ chunkProperties,
455
459
  );
456
-
457
- // Restore the parent summary builder and chunk summary path.
458
- this.trackedSummaryProperties.parentSummaryBuilder = parentSummaryBuilder;
459
- this.trackedSummaryProperties.chunkSummaryPath.pop();
460
+ chunkReferenceIds.push(chunkProperties.referenceId);
460
461
  }
461
-
462
- setInNestedMap(
463
- this.chunkTrackingPropertiesMap,
464
- this.trackedSummaryProperties.summarySequenceNumber,
465
- chunk,
466
- chunkProperties,
467
- );
468
- return [chunkReferenceId];
462
+ return chunkReferenceIds;
469
463
  }
470
464
 
471
465
  /**