@fluidframework/tree 2.53.1 → 2.60.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 (424) hide show
  1. package/.eslintrc.cjs +0 -19
  2. package/.mocharc.customBenchmarks.cjs +1 -9
  3. package/CHANGELOG.md +56 -0
  4. package/api-report/tree.alpha.api.md +50 -36
  5. package/api-report/tree.beta.api.md +15 -1
  6. package/api-report/{tree.legacy.alpha.api.md → tree.legacy.beta.api.md} +5 -5
  7. package/api-report/tree.legacy.public.api.md +1 -1
  8. package/api-report/tree.public.api.md +1 -1
  9. package/dist/alpha.d.ts +8 -2
  10. package/dist/beta.d.ts +3 -0
  11. package/dist/codec/codec.d.ts +43 -6
  12. package/dist/codec/codec.d.ts.map +1 -1
  13. package/dist/codec/codec.js +22 -2
  14. package/dist/codec/codec.js.map +1 -1
  15. package/dist/codec/index.d.ts +1 -1
  16. package/dist/codec/index.d.ts.map +1 -1
  17. package/dist/codec/index.js +4 -1
  18. package/dist/codec/index.js.map +1 -1
  19. package/dist/external-utilities/index.d.ts +1 -1
  20. package/dist/external-utilities/index.d.ts.map +1 -1
  21. package/dist/external-utilities/index.js +2 -1
  22. package/dist/external-utilities/index.js.map +1 -1
  23. package/dist/external-utilities/typeboxValidator.d.ts +6 -1
  24. package/dist/external-utilities/typeboxValidator.d.ts.map +1 -1
  25. package/dist/external-utilities/typeboxValidator.js +7 -1
  26. package/dist/external-utilities/typeboxValidator.js.map +1 -1
  27. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +10 -1
  28. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  29. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +28 -5
  30. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  31. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +19 -2
  32. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  33. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +10 -2
  34. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  35. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +59 -4
  36. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  37. package/dist/feature-libraries/chunked-forest/codec/codecs.js +9 -2
  38. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  39. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +46 -8
  40. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  41. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +91 -16
  42. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  43. package/dist/feature-libraries/chunked-forest/codec/format.d.ts +14 -0
  44. package/dist/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  45. package/dist/feature-libraries/chunked-forest/codec/format.js +10 -1
  46. package/dist/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  47. package/dist/feature-libraries/chunked-forest/codec/index.d.ts +1 -1
  48. package/dist/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
  49. package/dist/feature-libraries/chunked-forest/codec/index.js.map +1 -1
  50. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +8 -3
  51. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  52. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +17 -6
  53. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  54. package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
  55. package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  56. package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
  57. package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  58. package/dist/feature-libraries/forest-summary/codec.js +3 -0
  59. package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
  60. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +13 -8
  61. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  62. package/dist/feature-libraries/forest-summary/forestSummarizer.js +76 -38
  63. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  64. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +178 -0
  65. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -0
  66. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +322 -0
  67. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -0
  68. package/dist/feature-libraries/forest-summary/index.d.ts +1 -1
  69. package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
  70. package/dist/feature-libraries/forest-summary/index.js +2 -1
  71. package/dist/feature-libraries/forest-summary/index.js.map +1 -1
  72. package/dist/feature-libraries/index.d.ts +1 -1
  73. package/dist/feature-libraries/index.d.ts.map +1 -1
  74. package/dist/feature-libraries/index.js +2 -1
  75. package/dist/feature-libraries/index.js.map +1 -1
  76. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
  77. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  78. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +1 -1
  79. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  80. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts +6 -9
  81. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  82. package/dist/feature-libraries/treeCompressionUtils.d.ts +15 -0
  83. package/dist/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
  84. package/dist/feature-libraries/treeCompressionUtils.js +16 -1
  85. package/dist/feature-libraries/treeCompressionUtils.js.map +1 -1
  86. package/dist/index.d.ts +3 -3
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +6 -2
  89. package/dist/index.js.map +1 -1
  90. package/dist/jsonDomainSchema.d.ts +1 -1
  91. package/dist/jsonDomainSchema.d.ts.map +1 -1
  92. package/dist/packageVersion.d.ts +1 -1
  93. package/dist/packageVersion.js +1 -1
  94. package/dist/packageVersion.js.map +1 -1
  95. package/dist/shared-tree/schematizingTreeView.d.ts +1 -1
  96. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  97. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  98. package/dist/shared-tree/sharedTree.d.ts +23 -6
  99. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  100. package/dist/shared-tree/sharedTree.js +4 -1
  101. package/dist/shared-tree/sharedTree.js.map +1 -1
  102. package/dist/shared-tree/sharedTreeChangeFamily.d.ts +2 -2
  103. package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  104. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  105. package/dist/shared-tree/tree.d.ts.map +1 -1
  106. package/dist/shared-tree/tree.js +3 -0
  107. package/dist/shared-tree/tree.js.map +1 -1
  108. package/dist/shared-tree/treeAlpha.d.ts +9 -11
  109. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  110. package/dist/shared-tree/treeAlpha.js.map +1 -1
  111. package/dist/shared-tree/treeCheckout.d.ts +2 -2
  112. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  113. package/dist/shared-tree/treeCheckout.js.map +1 -1
  114. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  115. package/dist/shared-tree-core/sharedTreeCore.js +13 -0
  116. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  117. package/dist/sharedTreeAttributes.d.ts +2 -2
  118. package/dist/sharedTreeAttributes.js +2 -2
  119. package/dist/sharedTreeAttributes.js.map +1 -1
  120. package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
  121. package/dist/simple-tree/api/conciseTree.js +1 -1
  122. package/dist/simple-tree/api/conciseTree.js.map +1 -1
  123. package/dist/simple-tree/api/customTree.d.ts +39 -11
  124. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  125. package/dist/simple-tree/api/customTree.js +79 -19
  126. package/dist/simple-tree/api/customTree.js.map +1 -1
  127. package/dist/simple-tree/api/getJsonSchema.d.ts +7 -2
  128. package/dist/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  129. package/dist/simple-tree/api/getJsonSchema.js +1 -0
  130. package/dist/simple-tree/api/getJsonSchema.js.map +1 -1
  131. package/dist/simple-tree/api/index.d.ts +2 -1
  132. package/dist/simple-tree/api/index.d.ts.map +1 -1
  133. package/dist/simple-tree/api/index.js +4 -1
  134. package/dist/simple-tree/api/index.js.map +1 -1
  135. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +1 -1
  136. package/dist/simple-tree/api/schemaCreationUtilities.js +1 -1
  137. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  138. package/dist/simple-tree/api/schemaFactory.d.ts +9 -6
  139. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  140. package/dist/simple-tree/api/schemaFactory.js +8 -7
  141. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  142. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +13 -17
  143. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  144. package/dist/simple-tree/api/schemaFactoryAlpha.js +21 -25
  145. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  146. package/dist/simple-tree/api/schemaFactoryBeta.d.ts +20 -0
  147. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -0
  148. package/dist/simple-tree/api/schemaFactoryBeta.js +26 -0
  149. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -0
  150. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +0 -2
  151. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  152. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +6 -3
  153. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  154. package/dist/simple-tree/api/transactionTypes.d.ts +1 -0
  155. package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
  156. package/dist/simple-tree/api/transactionTypes.js.map +1 -1
  157. package/dist/simple-tree/api/tree.d.ts +68 -74
  158. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  159. package/dist/simple-tree/api/tree.js.map +1 -1
  160. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  161. package/dist/simple-tree/api/verboseTree.js +3 -3
  162. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  163. package/dist/simple-tree/core/simpleNodeSchemaBase.d.ts +6 -0
  164. package/dist/simple-tree/core/simpleNodeSchemaBase.d.ts.map +1 -1
  165. package/dist/simple-tree/core/simpleNodeSchemaBase.js.map +1 -1
  166. package/dist/simple-tree/fieldSchema.d.ts +3 -4
  167. package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
  168. package/dist/simple-tree/fieldSchema.js +0 -3
  169. package/dist/simple-tree/fieldSchema.js.map +1 -1
  170. package/dist/simple-tree/index.d.ts +1 -1
  171. package/dist/simple-tree/index.d.ts.map +1 -1
  172. package/dist/simple-tree/index.js +4 -2
  173. package/dist/simple-tree/index.js.map +1 -1
  174. package/dist/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
  175. package/dist/simple-tree/node-kinds/record/recordNode.js +2 -3
  176. package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  177. package/dist/simple-tree/simpleSchema.d.ts +12 -0
  178. package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
  179. package/dist/simple-tree/simpleSchema.js.map +1 -1
  180. package/dist/simple-tree/toStoredSchema.d.ts +0 -3
  181. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  182. package/dist/simple-tree/toStoredSchema.js +0 -3
  183. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  184. package/dist/tableSchema.d.ts +11 -80
  185. package/dist/tableSchema.d.ts.map +1 -1
  186. package/dist/tableSchema.js +200 -117
  187. package/dist/tableSchema.js.map +1 -1
  188. package/dist/treeFactory.d.ts +1 -2
  189. package/dist/treeFactory.d.ts.map +1 -1
  190. package/dist/treeFactory.js +1 -2
  191. package/dist/treeFactory.js.map +1 -1
  192. package/lib/alpha.d.ts +8 -2
  193. package/lib/beta.d.ts +3 -0
  194. package/lib/codec/codec.d.ts +43 -6
  195. package/lib/codec/codec.d.ts.map +1 -1
  196. package/lib/codec/codec.js +19 -1
  197. package/lib/codec/codec.js.map +1 -1
  198. package/lib/codec/index.d.ts +1 -1
  199. package/lib/codec/index.d.ts.map +1 -1
  200. package/lib/codec/index.js +1 -1
  201. package/lib/codec/index.js.map +1 -1
  202. package/lib/external-utilities/index.d.ts +1 -1
  203. package/lib/external-utilities/index.d.ts.map +1 -1
  204. package/lib/external-utilities/index.js +1 -1
  205. package/lib/external-utilities/index.js.map +1 -1
  206. package/lib/external-utilities/typeboxValidator.d.ts +6 -1
  207. package/lib/external-utilities/typeboxValidator.d.ts.map +1 -1
  208. package/lib/external-utilities/typeboxValidator.js +6 -0
  209. package/lib/external-utilities/typeboxValidator.js.map +1 -1
  210. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +10 -1
  211. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  212. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +27 -5
  213. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  214. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +19 -2
  215. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  216. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +10 -2
  217. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  218. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +59 -4
  219. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  220. package/lib/feature-libraries/chunked-forest/codec/codecs.js +10 -3
  221. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  222. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +46 -8
  223. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  224. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +87 -14
  225. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  226. package/lib/feature-libraries/chunked-forest/codec/format.d.ts +14 -0
  227. package/lib/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  228. package/lib/feature-libraries/chunked-forest/codec/format.js +9 -0
  229. package/lib/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  230. package/lib/feature-libraries/chunked-forest/codec/index.d.ts +1 -1
  231. package/lib/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
  232. package/lib/feature-libraries/chunked-forest/codec/index.js.map +1 -1
  233. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +8 -3
  234. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  235. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +18 -7
  236. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  237. package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
  238. package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  239. package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
  240. package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  241. package/lib/feature-libraries/forest-summary/codec.js +3 -0
  242. package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
  243. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +13 -8
  244. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  245. package/lib/feature-libraries/forest-summary/forestSummarizer.js +75 -37
  246. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  247. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +178 -0
  248. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -0
  249. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +318 -0
  250. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -0
  251. package/lib/feature-libraries/forest-summary/index.d.ts +1 -1
  252. package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
  253. package/lib/feature-libraries/forest-summary/index.js +1 -1
  254. package/lib/feature-libraries/forest-summary/index.js.map +1 -1
  255. package/lib/feature-libraries/index.d.ts +1 -1
  256. package/lib/feature-libraries/index.d.ts.map +1 -1
  257. package/lib/feature-libraries/index.js +1 -1
  258. package/lib/feature-libraries/index.js.map +1 -1
  259. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
  260. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  261. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +3 -3
  262. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  263. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts +6 -9
  264. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  265. package/lib/feature-libraries/treeCompressionUtils.d.ts +15 -0
  266. package/lib/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
  267. package/lib/feature-libraries/treeCompressionUtils.js +15 -0
  268. package/lib/feature-libraries/treeCompressionUtils.js.map +1 -1
  269. package/lib/index.d.ts +3 -3
  270. package/lib/index.d.ts.map +1 -1
  271. package/lib/index.js +4 -4
  272. package/lib/index.js.map +1 -1
  273. package/lib/jsonDomainSchema.d.ts +1 -1
  274. package/lib/jsonDomainSchema.d.ts.map +1 -1
  275. package/lib/packageVersion.d.ts +1 -1
  276. package/lib/packageVersion.js +1 -1
  277. package/lib/packageVersion.js.map +1 -1
  278. package/lib/shared-tree/schematizingTreeView.d.ts +1 -1
  279. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  280. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  281. package/lib/shared-tree/sharedTree.d.ts +23 -6
  282. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  283. package/lib/shared-tree/sharedTree.js +4 -1
  284. package/lib/shared-tree/sharedTree.js.map +1 -1
  285. package/lib/shared-tree/sharedTreeChangeFamily.d.ts +2 -2
  286. package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  287. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  288. package/lib/shared-tree/tree.d.ts.map +1 -1
  289. package/lib/shared-tree/tree.js +3 -0
  290. package/lib/shared-tree/tree.js.map +1 -1
  291. package/lib/shared-tree/treeAlpha.d.ts +9 -11
  292. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  293. package/lib/shared-tree/treeAlpha.js.map +1 -1
  294. package/lib/shared-tree/treeCheckout.d.ts +2 -2
  295. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  296. package/lib/shared-tree/treeCheckout.js.map +1 -1
  297. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  298. package/lib/shared-tree-core/sharedTreeCore.js +13 -0
  299. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  300. package/lib/sharedTreeAttributes.d.ts +2 -2
  301. package/lib/sharedTreeAttributes.js +2 -2
  302. package/lib/sharedTreeAttributes.js.map +1 -1
  303. package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
  304. package/lib/simple-tree/api/conciseTree.js +2 -2
  305. package/lib/simple-tree/api/conciseTree.js.map +1 -1
  306. package/lib/simple-tree/api/customTree.d.ts +39 -11
  307. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  308. package/lib/simple-tree/api/customTree.js +79 -19
  309. package/lib/simple-tree/api/customTree.js.map +1 -1
  310. package/lib/simple-tree/api/getJsonSchema.d.ts +7 -2
  311. package/lib/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  312. package/lib/simple-tree/api/getJsonSchema.js +1 -0
  313. package/lib/simple-tree/api/getJsonSchema.js.map +1 -1
  314. package/lib/simple-tree/api/index.d.ts +2 -1
  315. package/lib/simple-tree/api/index.d.ts.map +1 -1
  316. package/lib/simple-tree/api/index.js +2 -1
  317. package/lib/simple-tree/api/index.js.map +1 -1
  318. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +1 -1
  319. package/lib/simple-tree/api/schemaCreationUtilities.js +1 -1
  320. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  321. package/lib/simple-tree/api/schemaFactory.d.ts +9 -6
  322. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  323. package/lib/simple-tree/api/schemaFactory.js +6 -6
  324. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  325. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +13 -17
  326. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  327. package/lib/simple-tree/api/schemaFactoryAlpha.js +22 -26
  328. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  329. package/lib/simple-tree/api/schemaFactoryBeta.d.ts +20 -0
  330. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -0
  331. package/lib/simple-tree/api/schemaFactoryBeta.js +22 -0
  332. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -0
  333. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +0 -2
  334. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  335. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +6 -3
  336. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  337. package/lib/simple-tree/api/transactionTypes.d.ts +1 -0
  338. package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
  339. package/lib/simple-tree/api/transactionTypes.js.map +1 -1
  340. package/lib/simple-tree/api/tree.d.ts +68 -74
  341. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  342. package/lib/simple-tree/api/tree.js.map +1 -1
  343. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  344. package/lib/simple-tree/api/verboseTree.js +4 -4
  345. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  346. package/lib/simple-tree/core/simpleNodeSchemaBase.d.ts +6 -0
  347. package/lib/simple-tree/core/simpleNodeSchemaBase.d.ts.map +1 -1
  348. package/lib/simple-tree/core/simpleNodeSchemaBase.js.map +1 -1
  349. package/lib/simple-tree/fieldSchema.d.ts +3 -4
  350. package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
  351. package/lib/simple-tree/fieldSchema.js +0 -3
  352. package/lib/simple-tree/fieldSchema.js.map +1 -1
  353. package/lib/simple-tree/index.d.ts +1 -1
  354. package/lib/simple-tree/index.d.ts.map +1 -1
  355. package/lib/simple-tree/index.js +1 -1
  356. package/lib/simple-tree/index.js.map +1 -1
  357. package/lib/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
  358. package/lib/simple-tree/node-kinds/record/recordNode.js +2 -3
  359. package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  360. package/lib/simple-tree/simpleSchema.d.ts +12 -0
  361. package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
  362. package/lib/simple-tree/simpleSchema.js.map +1 -1
  363. package/lib/simple-tree/toStoredSchema.d.ts +0 -3
  364. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  365. package/lib/simple-tree/toStoredSchema.js +0 -3
  366. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  367. package/lib/tableSchema.d.ts +11 -80
  368. package/lib/tableSchema.d.ts.map +1 -1
  369. package/lib/tableSchema.js +201 -118
  370. package/lib/tableSchema.js.map +1 -1
  371. package/lib/treeFactory.d.ts +1 -2
  372. package/lib/treeFactory.d.ts.map +1 -1
  373. package/lib/treeFactory.js +1 -2
  374. package/lib/treeFactory.js.map +1 -1
  375. package/package.json +21 -21
  376. package/src/codec/codec.ts +52 -7
  377. package/src/codec/index.ts +4 -0
  378. package/src/external-utilities/index.ts +1 -1
  379. package/src/external-utilities/typeboxValidator.ts +7 -1
  380. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +38 -4
  381. package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +10 -3
  382. package/src/feature-libraries/chunked-forest/codec/codecs.ts +96 -8
  383. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +123 -19
  384. package/src/feature-libraries/chunked-forest/codec/format.ts +11 -0
  385. package/src/feature-libraries/chunked-forest/codec/index.ts +4 -0
  386. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +28 -3
  387. package/src/feature-libraries/chunked-forest/index.ts +2 -0
  388. package/src/feature-libraries/forest-summary/codec.ts +3 -0
  389. package/src/feature-libraries/forest-summary/forestSummarizer.ts +118 -50
  390. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +511 -0
  391. package/src/feature-libraries/forest-summary/index.ts +1 -1
  392. package/src/feature-libraries/index.ts +5 -1
  393. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +8 -4
  394. package/src/feature-libraries/treeCompressionUtils.ts +19 -0
  395. package/src/index.ts +6 -1
  396. package/src/packageVersion.ts +1 -1
  397. package/src/shared-tree/schematizingTreeView.ts +1 -1
  398. package/src/shared-tree/sharedTree.ts +37 -4
  399. package/src/shared-tree/sharedTreeChangeFamily.ts +2 -2
  400. package/src/shared-tree/tree.ts +3 -0
  401. package/src/shared-tree/treeAlpha.ts +10 -11
  402. package/src/shared-tree/treeCheckout.ts +2 -2
  403. package/src/shared-tree-core/sharedTreeCore.ts +17 -0
  404. package/src/sharedTreeAttributes.ts +2 -2
  405. package/src/simple-tree/api/conciseTree.ts +2 -1
  406. package/src/simple-tree/api/customTree.ts +102 -32
  407. package/src/simple-tree/api/getJsonSchema.ts +7 -2
  408. package/src/simple-tree/api/index.ts +3 -0
  409. package/src/simple-tree/api/schemaCreationUtilities.ts +1 -1
  410. package/src/simple-tree/api/schemaFactory.ts +21 -14
  411. package/src/simple-tree/api/schemaFactoryAlpha.ts +29 -30
  412. package/src/simple-tree/api/schemaFactoryBeta.ts +28 -0
  413. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +7 -3
  414. package/src/simple-tree/api/transactionTypes.ts +1 -0
  415. package/src/simple-tree/api/tree.ts +75 -81
  416. package/src/simple-tree/api/verboseTree.ts +42 -39
  417. package/src/simple-tree/core/simpleNodeSchemaBase.ts +6 -0
  418. package/src/simple-tree/fieldSchema.ts +3 -4
  419. package/src/simple-tree/index.ts +3 -0
  420. package/src/simple-tree/node-kinds/record/recordNode.ts +2 -3
  421. package/src/simple-tree/simpleSchema.ts +12 -0
  422. package/src/simple-tree/toStoredSchema.ts +0 -3
  423. package/src/tableSchema.ts +261 -243
  424. package/src/treeFactory.ts +1 -2
@@ -0,0 +1,511 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { assert } from "@fluidframework/core-utils/internal";
7
+ import type {
8
+ IExperimentalIncrementalSummaryContext,
9
+ ISummaryTreeWithStats,
10
+ } from "@fluidframework/runtime-definitions/internal";
11
+ import { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
12
+ import {
13
+ brand,
14
+ setInNestedMap,
15
+ tryGetFromNestedMap,
16
+ type JsonCompatible,
17
+ type NestedMap,
18
+ } from "../../util/index.js";
19
+ import type {
20
+ ChunkReferenceId,
21
+ EncodedFieldBatch,
22
+ IncrementalEncoderDecoder,
23
+ TreeChunk,
24
+ } from "../chunked-forest/index.js";
25
+ import type {
26
+ FieldKey,
27
+ ITreeCursorSynchronous,
28
+ TreeNodeSchemaIdentifier,
29
+ } from "../../core/index.js";
30
+ import { SummaryType } from "@fluidframework/driver-definitions";
31
+ import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
32
+ import type { ISnapshotTree } from "@fluidframework/driver-definitions/internal";
33
+ import { LoggingError } from "@fluidframework/telemetry-utils/internal";
34
+ import type { IFluidHandle } from "@fluidframework/core-interfaces";
35
+ import type { SummaryElementStringifier } from "../../shared-tree-core/index.js";
36
+
37
+ /**
38
+ * The key for the blob under ForestSummarizer's root.
39
+ * This blob contains the ForestCodec's output.
40
+ * See {@link ForestIncrementalSummaryBuilder} for details on the summary structure.
41
+ */
42
+ export const forestSummaryContentKey = "ForestTree";
43
+
44
+ /**
45
+ * The contents of an incremental chunk is under a summary tree node with its {@link ChunkReferenceId} as the key.
46
+ * The inline portion of the chunk content is encoded with the forest codec is stored in a blob with this key.
47
+ * The rest of the chunk contents is stored in the summary tree under the summary tree node.
48
+ * See the summary format in {@link ForestIncrementalSummaryBuilder} for more details.
49
+ */
50
+ const chunkContentsBlobKey = "contents";
51
+
52
+ /**
53
+ * State that tells whether a summary is currently being tracked.
54
+ */
55
+ export const ForestSummaryTrackingState = {
56
+ /** A summary is currently being tracked. */
57
+ Tracking: "Tracking",
58
+ /** A summary is ready to be tracked. */
59
+ ReadyToTrack: "ReadyToTrack",
60
+ } as const;
61
+ export type ForestSummaryTrackingState =
62
+ (typeof ForestSummaryTrackingState)[keyof typeof ForestSummaryTrackingState];
63
+
64
+ /**
65
+ * The properties of a chunk that is tracked for every summary.
66
+ * If a chunk doesn't change between summaries,
67
+ * these properties will be used to generate a summary handle for the chunk.
68
+ */
69
+ interface ChunkSummaryProperties {
70
+ /**
71
+ * The reference ID of the chunk which uniquely identifies it under its parent's summary tree.
72
+ * The summary for this chunk will be stored against this reference ID as key in the summary tree.
73
+ */
74
+ readonly referenceId: ChunkReferenceId;
75
+ /**
76
+ * The path for this chunk's summary in the summary tree relative to the forest's summary tree.
77
+ * This path is used to generate a summary handle for the chunk if it doesn't change between summaries.
78
+ */
79
+ readonly summaryPath: string;
80
+ }
81
+
82
+ /**
83
+ * The properties of a summary being tracked.
84
+ */
85
+ interface TrackedSummaryProperties {
86
+ /**
87
+ * The sequence number of the summary in progress.
88
+ */
89
+ readonly summarySequenceNumber: number;
90
+ /**
91
+ * The base path for the latest summary that was successful.
92
+ * This is used to generate summary handles.
93
+ */
94
+ readonly latestSummaryBasePath: string;
95
+ /**
96
+ * Whether the summary being tracked is a full tree summary.
97
+ * If true, the summary will not contain any summary handles. All chunks must be summarized in full.
98
+ */
99
+ readonly fullTree: boolean;
100
+ /**
101
+ * Represents the path of a chunk in the summary tree relative to the forest's summary tree.
102
+ * Each item in the array is the {@link ChunkReferenceId} of a chunk in the summary tree starting
103
+ * from the chunk under forest summary tree.
104
+ * When a chunk is summarized, this array will be used to generate the path for the chunk's summary in the
105
+ * summary tree.
106
+ */
107
+ readonly chunkSummaryPath: ChunkReferenceId[];
108
+ /**
109
+ * The parent summary builder to use to build the incremental summary tree.
110
+ * When a chunk is being summarized, it will add its summary to this builder against its reference ID.
111
+ */
112
+ parentSummaryBuilder: SummaryTreeBuilder;
113
+ /**
114
+ * Serializes content (including {@link (IFluidHandle:interface)}s) for adding to a summary blob.
115
+ */
116
+ stringify: SummaryElementStringifier;
117
+ }
118
+
119
+ /**
120
+ * The behavior of the forest's incremental summary - whether the summary should be a single blob or incremental.
121
+ */
122
+ export enum ForestIncrementalSummaryBehavior {
123
+ /**
124
+ * The forest can encode chunks incrementally, i.e., chunks that support incremental encoding will be encoded
125
+ * separately - they will be added to a separate tree.
126
+ * The incremental summary format is described in {@link ForestIncrementalSummaryBuilder}.
127
+ */
128
+ Incremental,
129
+ /**
130
+ * The forest should encode all of it's data in a single summary blob.
131
+ * @remarks
132
+ * The format of the summary will be the same as the old format (pre-incremental summaries) and is fully
133
+ * backwards compatible with the old format. The summary will basically look like an incremental summary
134
+ * with no incremental fields - it will only contain the "ForestTree" blob in the summary format described
135
+ * in {@link ForestIncrementalSummaryBuilder}.
136
+ */
137
+ SingleBlob,
138
+ }
139
+
140
+ /**
141
+ * Validates that a summary is currently being tracked and that the tracked summary properties are defined.
142
+ * @param forestSummaryState - The current state of the forest summary tracking.
143
+ * @param trackedSummaryProperties - The properties of the tracked summary, which must be available.
144
+ */
145
+ function validateTrackingSummary(
146
+ forestSummaryState: ForestSummaryTrackingState,
147
+ trackedSummaryProperties: TrackedSummaryProperties | undefined,
148
+ ): asserts trackedSummaryProperties is TrackedSummaryProperties {
149
+ assert(
150
+ forestSummaryState === ForestSummaryTrackingState.Tracking,
151
+ 0xc22 /* Not tracking a summary */,
152
+ );
153
+ assert(
154
+ trackedSummaryProperties !== undefined,
155
+ 0xc23 /* Tracked summary properties must be available when tracking a summary */,
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Validates that a summary is ready to be tracked and that the tracked summary properties are undefined.
161
+ * @param forestSummaryState - The current state of the forest summary tracking.
162
+ * @param trackedSummaryProperties - The properties of the tracked summary, which must be undefined.
163
+ */
164
+ function validateReadyToTrackSummary(
165
+ forestSummaryState: ForestSummaryTrackingState,
166
+ trackedSummaryProperties: TrackedSummaryProperties | undefined,
167
+ ): asserts trackedSummaryProperties is undefined {
168
+ assert(
169
+ forestSummaryState === ForestSummaryTrackingState.ReadyToTrack,
170
+ 0xc24 /* Already tracking a summary */,
171
+ );
172
+ assert(
173
+ trackedSummaryProperties === undefined,
174
+ 0xc25 /* Tracked summary properties must not be available when ready to track */,
175
+ );
176
+ }
177
+
178
+ /* eslint-disable jsdoc/check-indentation */
179
+ /**
180
+ * Tracks and builds the incremental summary tree for a forest where chunks that support incremental encoding are
181
+ * stored in a separate tree in the summary under its {@link ChunkReferenceId}.
182
+ * The summary tree for a chunk is self-sufficient and can be independently loaded and used to reconstruct the
183
+ * chunk's contents without any additional context from its parent.
184
+ *
185
+ * An example summary tree with incremental summary:
186
+ * Forest
187
+ * ├── ForestTree
188
+ * ├── 0
189
+ * | ├── contents
190
+ * | ├── 1
191
+ * | | ├── contents
192
+ * | | ├── 2
193
+ * | | | ├── contents
194
+ * | ├── 3 - ".../Forest/ForestTree/0/1/3"
195
+ * ├── 4
196
+ * | ├── contents
197
+ * | ├── ...
198
+ * ├── 5 - "/.../Forest/ForestTree/5"
199
+ * - Forest is a summary tree node added by the shared tree and contains the following:
200
+ * - The inline portion of the top-level forest content is stored in a summary blob called "ForestTree".
201
+ * It also contains the {@link ChunkReferenceId}s of the incremental chunks under it.
202
+ * - The summary for each incremental chunk under it is stored against its {@link ChunkReferenceId}.
203
+ * - For each chunk, the structure of the summary tree is the same as the Forest. It contains the following:
204
+ * - The inline portion of the chunk content is stored in a blob called "contents".
205
+ * It also contains the {@link ChunkReferenceId}s of the incremental chunks under it.
206
+ * - The summary for each incremental chunk under it is stored against its {@link ChunkReferenceId}.
207
+ * - Chunks that do not change between summaries are summarized as handles in the summary tree.
208
+ * @remarks
209
+ * It may seem inconsistent that although the structure for the top-level forest tree is similar to that of
210
+ * an incremental chunk, its content is stored in a summary blob called "ForestTree" while the content for
211
+ * the incremental chunks are stored in a summary blob called "contents".
212
+ * This is to keep this summary backwards compatible with old format (before incremental summaries were added)
213
+ * where the entire forest content was in a summary blob called "ForestTree". So, if incremental summaries were
214
+ * disabled, the forest content will be fully backwards compatible.
215
+ * Note that this limits reusing the root node in a location other than root and a non-root node in the root.
216
+ * We could phase this out by switching to write the top-level contents under "contents" if we want to support
217
+ * the above. However, there is no plan to do that for now.
218
+ *
219
+ * TODO: AB#46752
220
+ * Add strong types for the summary structure to document it better. It will help make it super clear what the actual
221
+ * format is in a way that can easily be linked to, documented and inspected.
222
+ */
223
+ /* eslint-enable jsdoc/check-indentation */
224
+ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecoder {
225
+ /**
226
+ * The next reference ID to use for a chunk.
227
+ */
228
+ private nextReferenceId: ChunkReferenceId = brand(0);
229
+
230
+ /**
231
+ * For a given summary sequence number, keeps track of a chunk's properties that will be used to generate
232
+ * a summary handle for the chunk if it does not change between summaries.
233
+ */
234
+ private readonly chunkTrackingPropertiesMap: NestedMap<
235
+ number,
236
+ TreeChunk,
237
+ ChunkSummaryProperties
238
+ > = new Map();
239
+
240
+ /**
241
+ * The state indicating whether a summary is currently being tracked or not.
242
+ */
243
+ public forestSummaryState: ForestSummaryTrackingState =
244
+ ForestSummaryTrackingState.ReadyToTrack;
245
+
246
+ /**
247
+ * The sequence number of the latest summary that was successful.
248
+ */
249
+ private latestSummarySequenceNumber: number = -1;
250
+
251
+ /**
252
+ * The current state of the summary being tracked.
253
+ * This is undefined if no summary is currently being tracked.
254
+ */
255
+ private trackedSummaryProperties: TrackedSummaryProperties | undefined;
256
+
257
+ /**
258
+ * A map of chunk reference IDs to their encoded contents. This is typically used during the loading of the
259
+ * forest to retrieve the contents of the chunks that were summarized incrementally.
260
+ */
261
+ private readonly encodedChunkContentsMap: Map<string, EncodedFieldBatch> = new Map();
262
+
263
+ public constructor(
264
+ private readonly enableIncrementalSummary: boolean,
265
+ private readonly getChunkAtCursor: (cursor: ITreeCursorSynchronous) => TreeChunk,
266
+ /**
267
+ * {@link IncrementalEncoder.shouldEncodeFieldIncrementally}
268
+ */
269
+ public readonly shouldEncodeFieldIncrementally: (
270
+ nodeIdentifier: TreeNodeSchemaIdentifier,
271
+ fieldKey: FieldKey,
272
+ ) => boolean,
273
+ ) {}
274
+
275
+ /**
276
+ * Must be called when the forest is loaded to download the encoded contents of incremental chunks.
277
+ * @param services - The channel storage service to use to access the snapshot tree and download the
278
+ * contents of the chunks.
279
+ * @param readAndParse - A function that reads and parses a blob from the storage service.
280
+ */
281
+ public async load(
282
+ services: IChannelStorageService,
283
+ readAndParseChunk: <T extends JsonCompatible<IFluidHandle>>(id: string) => Promise<T>,
284
+ ): Promise<void> {
285
+ const forestTree = services.getSnapshotTree?.();
286
+ // Snapshot tree should be available when loading forest's contents. However, it is an optional function
287
+ // and may not be implemented by the storage service.
288
+ if (forestTree === undefined) {
289
+ return;
290
+ }
291
+
292
+ // Downloads the contents of incremental chunks in the given snapshot tree. Also, recursively downloads
293
+ // the contents of incremental chunks in any sub-trees.
294
+ const downloadChunkContentsInTree = async (
295
+ snapshotTree: ISnapshotTree,
296
+ parentTreeKey: string,
297
+ ): Promise<void> => {
298
+ // All trees in the snapshot tree are for incremental chunks. The key is the chunk's reference ID
299
+ // and the value is the snapshot tree for the chunk.
300
+ for (const [chunkReferenceId, chunkSnapshotTree] of Object.entries(snapshotTree.trees)) {
301
+ const chunkSubTreePath = `${parentTreeKey}${chunkReferenceId}`;
302
+ const chunkContentsPath = `${chunkSubTreePath}/${chunkContentsBlobKey}`;
303
+ if (!(await services.contains(chunkContentsPath))) {
304
+ throw new LoggingError(
305
+ `SharedTree: Cannot find contents for incremental chunk ${chunkContentsPath}`,
306
+ );
307
+ }
308
+ const chunkContents = await readAndParseChunk<EncodedFieldBatch>(chunkContentsPath);
309
+ this.encodedChunkContentsMap.set(chunkReferenceId, chunkContents);
310
+
311
+ // Recursively download the contents of chunks in this chunk's sub tree.
312
+ await downloadChunkContentsInTree(chunkSnapshotTree, `${chunkSubTreePath}/`);
313
+ }
314
+ };
315
+ await downloadChunkContentsInTree(forestTree, "");
316
+ }
317
+
318
+ /**
319
+ * Must be called when starting a new forest summary to track it.
320
+ * @param fullTree - Whether the summary is a full tree summary. If true, the summary will not contain
321
+ * any summary handles. All chunks must be summarized in full.
322
+ * @param incrementalSummaryContext - The context for the incremental summary that contains the sequence numbers
323
+ * for the current and latest summaries.
324
+ * @param stringify - Serializes content (including {@link (IFluidHandle:interface)}s) for adding to a summary blob.
325
+ * @returns the behavior of the forest's incremental summary.
326
+ */
327
+ public startSummary(args: {
328
+ fullTree: boolean;
329
+ incrementalSummaryContext: IExperimentalIncrementalSummaryContext | undefined;
330
+ stringify: SummaryElementStringifier;
331
+ }): ForestIncrementalSummaryBehavior {
332
+ const { fullTree, incrementalSummaryContext, stringify } = args;
333
+ // If there is no incremental summary context, do not summarize incrementally. This happens in two scenarios:
334
+ // 1. When summarizing a detached container, i.e., the first ever summary.
335
+ // 2. When running GC, the default behavior is to call summarize on DDS without incrementalSummaryContext.
336
+ if (!this.enableIncrementalSummary || incrementalSummaryContext === undefined) {
337
+ return ForestIncrementalSummaryBehavior.SingleBlob;
338
+ }
339
+
340
+ validateReadyToTrackSummary(this.forestSummaryState, this.trackedSummaryProperties);
341
+
342
+ this.forestSummaryState = ForestSummaryTrackingState.Tracking;
343
+ this.latestSummarySequenceNumber = incrementalSummaryContext.latestSummarySequenceNumber;
344
+ this.trackedSummaryProperties = {
345
+ summarySequenceNumber: incrementalSummaryContext.summarySequenceNumber,
346
+ latestSummaryBasePath: incrementalSummaryContext.summaryPath,
347
+ chunkSummaryPath: [],
348
+ parentSummaryBuilder: new SummaryTreeBuilder(),
349
+ fullTree,
350
+ stringify,
351
+ };
352
+ return ForestIncrementalSummaryBehavior.Incremental;
353
+ }
354
+
355
+ /**
356
+ * {@link IncrementalEncoder.encodeIncrementalField}
357
+ * @remarks Returns an empty array if the field has no content.
358
+ */
359
+ public encodeIncrementalField(
360
+ cursor: ITreeCursorSynchronous,
361
+ chunkEncoder: (chunk: TreeChunk) => EncodedFieldBatch,
362
+ ): ChunkReferenceId[] {
363
+ // Validate that a summary is currently being tracked and that the tracked summary properties are defined.
364
+ validateTrackingSummary(this.forestSummaryState, this.trackedSummaryProperties);
365
+
366
+ if (cursor.getFieldLength() === 0) {
367
+ return [];
368
+ }
369
+
370
+ let chunkReferenceId: ChunkReferenceId;
371
+ let chunkProperties: ChunkSummaryProperties;
372
+
373
+ const chunk = this.getChunkAtCursor(cursor);
374
+
375
+ // Try and get the properties of the chunk from the latest successful summary.
376
+ // If it exists and the summary is not a full tree, use the properties to generate a summary handle.
377
+ // If it does not exist, encode the chunk and generate new properties for it.
378
+ const previousChunkProperties = tryGetFromNestedMap(
379
+ this.chunkTrackingPropertiesMap,
380
+ this.latestSummarySequenceNumber,
381
+ chunk,
382
+ );
383
+ if (previousChunkProperties !== undefined && !this.trackedSummaryProperties.fullTree) {
384
+ chunkProperties = previousChunkProperties;
385
+ chunkReferenceId = previousChunkProperties.referenceId;
386
+ this.trackedSummaryProperties.parentSummaryBuilder.addHandle(
387
+ `${chunkReferenceId}`,
388
+ SummaryType.Tree,
389
+ `${this.trackedSummaryProperties.latestSummaryBasePath}/${previousChunkProperties.summaryPath}`,
390
+ );
391
+ } else {
392
+ // Generate a new reference ID for the chunk.
393
+ chunkReferenceId = brand(this.nextReferenceId++);
394
+ // Add the reference ID of this chunk to the chunk summary path and use the path as the summary path
395
+ // for the chunk in its summary properties.
396
+ // This is done before encoding the chunk so that the summary path is updated correctly when encoding
397
+ // any incremental chunks that are under this chunk.
398
+ this.trackedSummaryProperties.chunkSummaryPath.push(chunkReferenceId);
399
+
400
+ chunkProperties = {
401
+ referenceId: chunkReferenceId,
402
+ summaryPath: this.trackedSummaryProperties.chunkSummaryPath.join("/"),
403
+ };
404
+
405
+ const parentSummaryBuilder = this.trackedSummaryProperties.parentSummaryBuilder;
406
+ // Create a new summary builder for this chunk to build its summary tree which will be stored in the
407
+ // parent's summary tree under its reference ID.
408
+ // Before encoding the chunk, set the parent summary builder to this chunk's summary builder so that
409
+ // any incremental chunks in the subtree of this chunk will use that as their parent summary builder.
410
+ const chunkSummaryBuilder = new SummaryTreeBuilder();
411
+ this.trackedSummaryProperties.parentSummaryBuilder = chunkSummaryBuilder;
412
+ chunkSummaryBuilder.addBlob(
413
+ chunkContentsBlobKey,
414
+ this.trackedSummaryProperties.stringify(chunkEncoder(chunk)),
415
+ );
416
+
417
+ // Add this chunk's summary tree to the parent's summary tree. The summary tree contains its encoded
418
+ // contents and the summary trees of any incremental chunks under it.
419
+ parentSummaryBuilder.addWithStats(
420
+ `${chunkReferenceId}`,
421
+ chunkSummaryBuilder.getSummaryTree(),
422
+ );
423
+
424
+ // Restore the parent summary builder and chunk summary path.
425
+ this.trackedSummaryProperties.parentSummaryBuilder = parentSummaryBuilder;
426
+ this.trackedSummaryProperties.chunkSummaryPath.pop();
427
+ }
428
+
429
+ setInNestedMap(
430
+ this.chunkTrackingPropertiesMap,
431
+ this.trackedSummaryProperties.summarySequenceNumber,
432
+ chunk,
433
+ chunkProperties,
434
+ );
435
+ return [chunkReferenceId];
436
+ }
437
+
438
+ /**
439
+ * Must be called after summary generation is complete to finish tracking the summary.
440
+ * It clears any tracking state and deletes the tracking properties for summaries that are older than the
441
+ * latest successful summary.
442
+ * @param incrementalSummaryContext - The context for the incremental summary that contains the sequence numbers.
443
+ * If this is undefined, the summary tree will only contain a summary blob for `forestSummaryContent`.
444
+ * @param forestSummaryContent - The stringified ForestCodec output of top-level Forest content.
445
+ * @returns the Forest's summary tree.
446
+ */
447
+ public completeSummary(args: {
448
+ incrementalSummaryContext: IExperimentalIncrementalSummaryContext | undefined;
449
+ forestSummaryContent: string;
450
+ }): ISummaryTreeWithStats {
451
+ const { incrementalSummaryContext, forestSummaryContent } = args;
452
+ if (!this.enableIncrementalSummary || incrementalSummaryContext === undefined) {
453
+ const summaryBuilder = new SummaryTreeBuilder();
454
+ summaryBuilder.addBlob(forestSummaryContentKey, forestSummaryContent);
455
+ return summaryBuilder.getSummaryTree();
456
+ }
457
+
458
+ validateTrackingSummary(this.forestSummaryState, this.trackedSummaryProperties);
459
+
460
+ this.trackedSummaryProperties.parentSummaryBuilder.addBlob(
461
+ forestSummaryContentKey,
462
+ forestSummaryContent,
463
+ );
464
+
465
+ // Copy over the entries from the latest summary to the current summary.
466
+ // In the current summary, there can be fields that haven't changed since the latest summary and the chunks
467
+ // in these fields and in any of its children weren't encoded. So, we need get the entries for these chunks
468
+ // to be able to incrementally summarize them in the next summary.
469
+ const latestSummaryTrackingMap = this.chunkTrackingPropertiesMap.get(
470
+ this.latestSummarySequenceNumber,
471
+ );
472
+ const currentSummaryTrackingMap = this.chunkTrackingPropertiesMap.get(
473
+ this.trackedSummaryProperties.summarySequenceNumber,
474
+ );
475
+ if (latestSummaryTrackingMap !== undefined && currentSummaryTrackingMap !== undefined) {
476
+ for (const [chunk, chunkProperties] of latestSummaryTrackingMap.entries()) {
477
+ if (!currentSummaryTrackingMap.has(chunk)) {
478
+ currentSummaryTrackingMap.set(chunk, chunkProperties);
479
+ }
480
+ }
481
+ }
482
+
483
+ // Delete tracking for summaries that are older than the latest successful summary because they will
484
+ // never be referenced again for generating summary handles.
485
+ for (const sequenceNumber of this.chunkTrackingPropertiesMap.keys()) {
486
+ if (sequenceNumber < this.latestSummarySequenceNumber) {
487
+ this.chunkTrackingPropertiesMap.delete(sequenceNumber);
488
+ }
489
+ }
490
+
491
+ this.forestSummaryState = ForestSummaryTrackingState.ReadyToTrack;
492
+ const summaryTree = this.trackedSummaryProperties.parentSummaryBuilder.getSummaryTree();
493
+ this.trackedSummaryProperties = undefined;
494
+ return summaryTree;
495
+ }
496
+
497
+ /**
498
+ * Called to get the encoded contents of an incremental chunk with the given reference ID.
499
+ * This is typically used when loading the forest to retrieve the contents of incremental chunks.
500
+ * @param referenceId - The reference ID of the chunk to retrieve.
501
+ * @returns The encoded contents of the chunk.
502
+ */
503
+ public getEncodedIncrementalChunk(referenceId: ChunkReferenceId): EncodedFieldBatch {
504
+ const chunkEncodedContents = this.encodedChunkContentsMap.get(`${referenceId}`);
505
+ assert(
506
+ chunkEncodedContents !== undefined,
507
+ 0xc26 /* Incremental chunk contents not found */,
508
+ );
509
+ return chunkEncodedContents;
510
+ }
511
+ }
@@ -3,4 +3,4 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- export { ForestSummarizer } from "./forestSummarizer.js";
6
+ export { forestSummaryKey, ForestSummarizer } from "./forestSummarizer.js";
@@ -173,7 +173,11 @@ export {
173
173
  getOrCreateHydratedFlexTreeNode,
174
174
  } from "./flex-tree/index.js";
175
175
 
176
- export { TreeCompressionStrategy } from "./treeCompressionUtils.js";
176
+ export {
177
+ TreeCompressionStrategy,
178
+ TreeCompressionStrategyExtended,
179
+ type TreeCompressionStrategyPrivate,
180
+ } from "./treeCompressionUtils.js";
177
181
 
178
182
  export { valueSchemaAllows } from "./valueUtilities.js";
179
183
 
@@ -12,6 +12,7 @@ import {
12
12
  type IJsonCodec,
13
13
  type IMultiFormatCodec,
14
14
  type SchemaValidationFunction,
15
+ extractJsonValidator,
15
16
  makeCodecFamily,
16
17
  withSchemaValidation,
17
18
  } from "../../codec/index.js";
@@ -39,7 +40,10 @@ import {
39
40
  chunkFieldSingle,
40
41
  defaultChunkPolicy,
41
42
  } from "../chunked-forest/index.js";
42
- import { TreeCompressionStrategy } from "../treeCompressionUtils.js";
43
+ import {
44
+ TreeCompressionStrategy,
45
+ type TreeCompressionStrategyPrivate,
46
+ } from "../treeCompressionUtils.js";
43
47
 
44
48
  import type { FieldChangeEncodingContext, FieldChangeHandler } from "./fieldChangeHandler.js";
45
49
  import type {
@@ -77,7 +81,7 @@ export function makeModularChangeCodecFamily(
77
81
  >,
78
82
  fieldsCodec: FieldBatchCodec,
79
83
  codecOptions: ICodecOptions,
80
- chunkCompressionStrategy: TreeCompressionStrategy = TreeCompressionStrategy.Compressed,
84
+ chunkCompressionStrategy: TreeCompressionStrategyPrivate = TreeCompressionStrategy.Compressed,
81
85
  ): ICodecFamily<ModularChangeset, ChangeEncodingContext> {
82
86
  return makeCodecFamily(
83
87
  Array.from(fieldKindConfigurations.entries(), ([version, fieldKinds]) => [
@@ -117,7 +121,7 @@ function makeModularChangeCodec(
117
121
  >,
118
122
  fieldsCodec: FieldBatchCodec,
119
123
  codecOptions: ICodecOptions,
120
- chunkCompressionStrategy: TreeCompressionStrategy = TreeCompressionStrategy.Compressed,
124
+ chunkCompressionStrategy: TreeCompressionStrategyPrivate = TreeCompressionStrategy.Compressed,
121
125
  ): ModularChangeCodec {
122
126
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
123
127
  const getMapEntry = ({ kind, formatVersion }: FieldKindConfigurationEntry) => {
@@ -125,7 +129,7 @@ function makeModularChangeCodec(
125
129
  return {
126
130
  codec,
127
131
  compiledSchema: codec.json.encodedSchema
128
- ? codecOptions.jsonValidator.compile(codec.json.encodedSchema)
132
+ ? extractJsonValidator(codecOptions.jsonValidator).compile(codec.json.encodedSchema)
129
133
  : undefined,
130
134
  };
131
135
  };
@@ -21,3 +21,22 @@ export enum TreeCompressionStrategy {
21
21
  */
22
22
  Uncompressed = 1,
23
23
  }
24
+
25
+ /**
26
+ * A private extension of {@link TreeCompressionStrategy} for strategies that are not intended for public use just yet.
27
+ */
28
+ export enum TreeCompressionStrategyExtended {
29
+ /**
30
+ * Optimized for encoded size, same as TreeCompressionStrategy.Compressed. It also enables incremental encoding
31
+ * of the data.
32
+ * @remarks
33
+ * TODO: AB#41865
34
+ * This needs to be stabilized to allow opting into it.
35
+ * It could possibly be made the default instead of {@link TreeCompressionStrategy.Compressed}.
36
+ */
37
+ CompressedIncremental = 2,
38
+ }
39
+
40
+ export type TreeCompressionStrategyPrivate =
41
+ | TreeCompressionStrategy
42
+ | TreeCompressionStrategyExtended;
package/src/index.ts CHANGED
@@ -90,6 +90,7 @@ export {
90
90
  type TreeView,
91
91
  type TreeViewEvents,
92
92
  SchemaFactory,
93
+ SchemaFactoryBeta,
93
94
  SchemaFactoryAlpha,
94
95
  type SchemaFactoryObjectOptions,
95
96
  type ImplicitFieldSchema,
@@ -264,6 +265,8 @@ export {
264
265
  type RecordNodeInsertableData,
265
266
  type RecordNodePojoEmulationSchema,
266
267
  type TreeRecordNode,
268
+ KeyEncodingOptions,
269
+ type TreeParsingOptions,
267
270
  } from "./simple-tree/index.js";
268
271
  export {
269
272
  SharedTree,
@@ -278,9 +281,11 @@ export {
278
281
  type JsonValidator,
279
282
  type SchemaValidationFunction,
280
283
  FluidClientVersion,
284
+ type FormatValidator,
285
+ FormatValidatorNoOp,
281
286
  } from "./codec/index.js";
282
287
  export { noopValidator } from "./codec/index.js";
283
- export { typeboxValidator } from "./external-utilities/index.js";
288
+ export { typeboxValidator, FormatValidatorBasic } from "./external-utilities/index.js";
284
289
 
285
290
  export type {
286
291
  // Type Testing
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/tree";
9
- export const pkgVersion = "2.53.1";
9
+ export const pkgVersion = "2.60.0";
@@ -79,7 +79,7 @@ export const ViewSlot = anchorSlot<TreeView<ImplicitFieldSchema>>();
79
79
  @breakingClass
80
80
  export class SchematizingSimpleTreeView<
81
81
  in out TRootSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,
82
- > implements TreeBranch, TreeViewAlpha<TRootSchema>, WithBreakable
82
+ > implements TreeViewAlpha<TRootSchema>, WithBreakable
83
83
  {
84
84
  /**
85
85
  * This is set to undefined when this object is disposed or the view schema does not support viewing the document's stored schema.