@fluidframework/tree 2.53.1 → 2.61.0-355054

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 (452) hide show
  1. package/.eslintrc.cjs +0 -19
  2. package/.mocharc.cjs +2 -3
  3. package/.mocharc.customBenchmarks.cjs +1 -9
  4. package/CHANGELOG.md +56 -0
  5. package/alpha.d.ts +1 -1
  6. package/api-report/tree.alpha.api.md +51 -37
  7. package/api-report/tree.beta.api.md +16 -2
  8. package/api-report/{tree.legacy.alpha.api.md → tree.legacy.beta.api.md} +72 -6
  9. package/api-report/tree.legacy.public.api.md +2 -2
  10. package/api-report/tree.public.api.md +2 -2
  11. package/beta.d.ts +1 -1
  12. package/dist/alpha.d.ts +17 -7
  13. package/dist/beta.d.ts +10 -4
  14. package/dist/codec/codec.d.ts +43 -6
  15. package/dist/codec/codec.d.ts.map +1 -1
  16. package/dist/codec/codec.js +22 -2
  17. package/dist/codec/codec.js.map +1 -1
  18. package/dist/codec/index.d.ts +1 -1
  19. package/dist/codec/index.d.ts.map +1 -1
  20. package/dist/codec/index.js +4 -1
  21. package/dist/codec/index.js.map +1 -1
  22. package/dist/external-utilities/index.d.ts +1 -1
  23. package/dist/external-utilities/index.d.ts.map +1 -1
  24. package/dist/external-utilities/index.js +2 -1
  25. package/dist/external-utilities/index.js.map +1 -1
  26. package/dist/external-utilities/typeboxValidator.d.ts +6 -1
  27. package/dist/external-utilities/typeboxValidator.d.ts.map +1 -1
  28. package/dist/external-utilities/typeboxValidator.js +7 -1
  29. package/dist/external-utilities/typeboxValidator.js.map +1 -1
  30. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +10 -1
  31. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  32. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +28 -5
  33. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  34. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +19 -2
  35. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +10 -2
  37. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +59 -4
  39. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  40. package/dist/feature-libraries/chunked-forest/codec/codecs.js +9 -2
  41. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  42. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +46 -8
  43. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +91 -16
  45. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  46. package/dist/feature-libraries/chunked-forest/codec/format.d.ts +14 -0
  47. package/dist/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  48. package/dist/feature-libraries/chunked-forest/codec/format.js +10 -1
  49. package/dist/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  50. package/dist/feature-libraries/chunked-forest/codec/index.d.ts +1 -1
  51. package/dist/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
  52. package/dist/feature-libraries/chunked-forest/codec/index.js.map +1 -1
  53. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +8 -3
  54. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  55. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +17 -6
  56. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  57. package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
  58. package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  59. package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
  60. package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  61. package/dist/feature-libraries/forest-summary/codec.js +3 -0
  62. package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
  63. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +13 -8
  64. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  65. package/dist/feature-libraries/forest-summary/forestSummarizer.js +76 -38
  66. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  67. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +178 -0
  68. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -0
  69. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +322 -0
  70. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -0
  71. package/dist/feature-libraries/forest-summary/index.d.ts +1 -1
  72. package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
  73. package/dist/feature-libraries/forest-summary/index.js +2 -1
  74. package/dist/feature-libraries/forest-summary/index.js.map +1 -1
  75. package/dist/feature-libraries/index.d.ts +1 -1
  76. package/dist/feature-libraries/index.d.ts.map +1 -1
  77. package/dist/feature-libraries/index.js +2 -1
  78. package/dist/feature-libraries/index.js.map +1 -1
  79. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
  80. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  81. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +1 -1
  82. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  83. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts +6 -9
  84. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  85. package/dist/feature-libraries/treeCompressionUtils.d.ts +15 -0
  86. package/dist/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
  87. package/dist/feature-libraries/treeCompressionUtils.js +16 -1
  88. package/dist/feature-libraries/treeCompressionUtils.js.map +1 -1
  89. package/dist/index.d.ts +3 -3
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +6 -2
  92. package/dist/index.js.map +1 -1
  93. package/dist/jsonDomainSchema.d.ts +1 -1
  94. package/dist/jsonDomainSchema.d.ts.map +1 -1
  95. package/dist/legacy.d.ts +21 -4
  96. package/dist/packageVersion.d.ts +1 -1
  97. package/dist/packageVersion.d.ts.map +1 -1
  98. package/dist/packageVersion.js +1 -1
  99. package/dist/packageVersion.js.map +1 -1
  100. package/dist/public.d.ts +5 -3
  101. package/dist/shared-tree/schematizingTreeView.d.ts +1 -1
  102. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  103. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  104. package/dist/shared-tree/sharedTree.d.ts +23 -6
  105. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  106. package/dist/shared-tree/sharedTree.js +4 -1
  107. package/dist/shared-tree/sharedTree.js.map +1 -1
  108. package/dist/shared-tree/sharedTreeChangeFamily.d.ts +2 -2
  109. package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  110. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  111. package/dist/shared-tree/tree.d.ts.map +1 -1
  112. package/dist/shared-tree/tree.js +3 -0
  113. package/dist/shared-tree/tree.js.map +1 -1
  114. package/dist/shared-tree/treeAlpha.d.ts +9 -11
  115. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  116. package/dist/shared-tree/treeAlpha.js.map +1 -1
  117. package/dist/shared-tree/treeCheckout.d.ts +2 -2
  118. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  119. package/dist/shared-tree/treeCheckout.js +1 -0
  120. package/dist/shared-tree/treeCheckout.js.map +1 -1
  121. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  122. package/dist/shared-tree-core/sharedTreeCore.js +13 -0
  123. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  124. package/dist/sharedTreeAttributes.d.ts +2 -2
  125. package/dist/sharedTreeAttributes.js +2 -2
  126. package/dist/sharedTreeAttributes.js.map +1 -1
  127. package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
  128. package/dist/simple-tree/api/conciseTree.js +1 -1
  129. package/dist/simple-tree/api/conciseTree.js.map +1 -1
  130. package/dist/simple-tree/api/customTree.d.ts +39 -11
  131. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  132. package/dist/simple-tree/api/customTree.js +79 -19
  133. package/dist/simple-tree/api/customTree.js.map +1 -1
  134. package/dist/simple-tree/api/getJsonSchema.d.ts +7 -2
  135. package/dist/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  136. package/dist/simple-tree/api/getJsonSchema.js +1 -0
  137. package/dist/simple-tree/api/getJsonSchema.js.map +1 -1
  138. package/dist/simple-tree/api/index.d.ts +2 -1
  139. package/dist/simple-tree/api/index.d.ts.map +1 -1
  140. package/dist/simple-tree/api/index.js +4 -1
  141. package/dist/simple-tree/api/index.js.map +1 -1
  142. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +1 -1
  143. package/dist/simple-tree/api/schemaCreationUtilities.js +1 -1
  144. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  145. package/dist/simple-tree/api/schemaFactory.d.ts +9 -6
  146. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  147. package/dist/simple-tree/api/schemaFactory.js +8 -7
  148. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  149. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +13 -17
  150. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  151. package/dist/simple-tree/api/schemaFactoryAlpha.js +21 -25
  152. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  153. package/dist/simple-tree/api/schemaFactoryBeta.d.ts +20 -0
  154. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -0
  155. package/dist/simple-tree/api/schemaFactoryBeta.js +26 -0
  156. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -0
  157. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +5 -3
  158. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  159. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  160. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +0 -2
  161. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  162. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +6 -3
  163. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  164. package/dist/simple-tree/api/transactionTypes.d.ts +1 -0
  165. package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
  166. package/dist/simple-tree/api/transactionTypes.js.map +1 -1
  167. package/dist/simple-tree/api/tree.d.ts +68 -74
  168. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  169. package/dist/simple-tree/api/tree.js.map +1 -1
  170. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  171. package/dist/simple-tree/api/verboseTree.js +3 -3
  172. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  173. package/dist/simple-tree/core/simpleNodeSchemaBase.d.ts +6 -0
  174. package/dist/simple-tree/core/simpleNodeSchemaBase.d.ts.map +1 -1
  175. package/dist/simple-tree/core/simpleNodeSchemaBase.js.map +1 -1
  176. package/dist/simple-tree/fieldSchema.d.ts +3 -4
  177. package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
  178. package/dist/simple-tree/fieldSchema.js +0 -3
  179. package/dist/simple-tree/fieldSchema.js.map +1 -1
  180. package/dist/simple-tree/index.d.ts +1 -1
  181. package/dist/simple-tree/index.d.ts.map +1 -1
  182. package/dist/simple-tree/index.js +4 -2
  183. package/dist/simple-tree/index.js.map +1 -1
  184. package/dist/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
  185. package/dist/simple-tree/node-kinds/record/recordNode.js +2 -3
  186. package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  187. package/dist/simple-tree/simpleSchema.d.ts +12 -0
  188. package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
  189. package/dist/simple-tree/simpleSchema.js.map +1 -1
  190. package/dist/simple-tree/toStoredSchema.d.ts +0 -3
  191. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  192. package/dist/simple-tree/toStoredSchema.js +0 -3
  193. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  194. package/dist/tableSchema.d.ts +11 -80
  195. package/dist/tableSchema.d.ts.map +1 -1
  196. package/dist/tableSchema.js +200 -117
  197. package/dist/tableSchema.js.map +1 -1
  198. package/dist/treeFactory.d.ts +1 -2
  199. package/dist/treeFactory.d.ts.map +1 -1
  200. package/dist/treeFactory.js +1 -2
  201. package/dist/treeFactory.js.map +1 -1
  202. package/dist/util/breakable.d.ts.map +1 -1
  203. package/dist/util/breakable.js +7 -1
  204. package/dist/util/breakable.js.map +1 -1
  205. package/internal.d.ts +1 -1
  206. package/legacy.d.ts +1 -1
  207. package/lib/alpha.d.ts +17 -7
  208. package/lib/beta.d.ts +10 -4
  209. package/lib/codec/codec.d.ts +43 -6
  210. package/lib/codec/codec.d.ts.map +1 -1
  211. package/lib/codec/codec.js +19 -1
  212. package/lib/codec/codec.js.map +1 -1
  213. package/lib/codec/index.d.ts +1 -1
  214. package/lib/codec/index.d.ts.map +1 -1
  215. package/lib/codec/index.js +1 -1
  216. package/lib/codec/index.js.map +1 -1
  217. package/lib/external-utilities/index.d.ts +1 -1
  218. package/lib/external-utilities/index.d.ts.map +1 -1
  219. package/lib/external-utilities/index.js +1 -1
  220. package/lib/external-utilities/index.js.map +1 -1
  221. package/lib/external-utilities/typeboxValidator.d.ts +6 -1
  222. package/lib/external-utilities/typeboxValidator.d.ts.map +1 -1
  223. package/lib/external-utilities/typeboxValidator.js +6 -0
  224. package/lib/external-utilities/typeboxValidator.js.map +1 -1
  225. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +10 -1
  226. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  227. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +27 -5
  228. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  229. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +19 -2
  230. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  231. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +10 -2
  232. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  233. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +59 -4
  234. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  235. package/lib/feature-libraries/chunked-forest/codec/codecs.js +10 -3
  236. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  237. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +46 -8
  238. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  239. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +87 -14
  240. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  241. package/lib/feature-libraries/chunked-forest/codec/format.d.ts +14 -0
  242. package/lib/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  243. package/lib/feature-libraries/chunked-forest/codec/format.js +9 -0
  244. package/lib/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  245. package/lib/feature-libraries/chunked-forest/codec/index.d.ts +1 -1
  246. package/lib/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
  247. package/lib/feature-libraries/chunked-forest/codec/index.js.map +1 -1
  248. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +8 -3
  249. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  250. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +18 -7
  251. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  252. package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
  253. package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  254. package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
  255. package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  256. package/lib/feature-libraries/forest-summary/codec.js +3 -0
  257. package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
  258. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +13 -8
  259. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  260. package/lib/feature-libraries/forest-summary/forestSummarizer.js +75 -37
  261. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  262. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +178 -0
  263. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -0
  264. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +318 -0
  265. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -0
  266. package/lib/feature-libraries/forest-summary/index.d.ts +1 -1
  267. package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
  268. package/lib/feature-libraries/forest-summary/index.js +1 -1
  269. package/lib/feature-libraries/forest-summary/index.js.map +1 -1
  270. package/lib/feature-libraries/index.d.ts +1 -1
  271. package/lib/feature-libraries/index.d.ts.map +1 -1
  272. package/lib/feature-libraries/index.js +1 -1
  273. package/lib/feature-libraries/index.js.map +1 -1
  274. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
  275. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  276. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +3 -3
  277. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  278. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts +6 -9
  279. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  280. package/lib/feature-libraries/treeCompressionUtils.d.ts +15 -0
  281. package/lib/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
  282. package/lib/feature-libraries/treeCompressionUtils.js +15 -0
  283. package/lib/feature-libraries/treeCompressionUtils.js.map +1 -1
  284. package/lib/index.d.ts +3 -3
  285. package/lib/index.d.ts.map +1 -1
  286. package/lib/index.js +4 -4
  287. package/lib/index.js.map +1 -1
  288. package/lib/jsonDomainSchema.d.ts +1 -1
  289. package/lib/jsonDomainSchema.d.ts.map +1 -1
  290. package/lib/legacy.d.ts +21 -4
  291. package/lib/packageVersion.d.ts +1 -1
  292. package/lib/packageVersion.d.ts.map +1 -1
  293. package/lib/packageVersion.js +1 -1
  294. package/lib/packageVersion.js.map +1 -1
  295. package/lib/public.d.ts +5 -3
  296. package/lib/shared-tree/schematizingTreeView.d.ts +1 -1
  297. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  298. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  299. package/lib/shared-tree/sharedTree.d.ts +23 -6
  300. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  301. package/lib/shared-tree/sharedTree.js +4 -1
  302. package/lib/shared-tree/sharedTree.js.map +1 -1
  303. package/lib/shared-tree/sharedTreeChangeFamily.d.ts +2 -2
  304. package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  305. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  306. package/lib/shared-tree/tree.d.ts.map +1 -1
  307. package/lib/shared-tree/tree.js +3 -0
  308. package/lib/shared-tree/tree.js.map +1 -1
  309. package/lib/shared-tree/treeAlpha.d.ts +9 -11
  310. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  311. package/lib/shared-tree/treeAlpha.js.map +1 -1
  312. package/lib/shared-tree/treeCheckout.d.ts +2 -2
  313. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  314. package/lib/shared-tree/treeCheckout.js +1 -0
  315. package/lib/shared-tree/treeCheckout.js.map +1 -1
  316. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  317. package/lib/shared-tree-core/sharedTreeCore.js +13 -0
  318. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  319. package/lib/sharedTreeAttributes.d.ts +2 -2
  320. package/lib/sharedTreeAttributes.js +2 -2
  321. package/lib/sharedTreeAttributes.js.map +1 -1
  322. package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
  323. package/lib/simple-tree/api/conciseTree.js +2 -2
  324. package/lib/simple-tree/api/conciseTree.js.map +1 -1
  325. package/lib/simple-tree/api/customTree.d.ts +39 -11
  326. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  327. package/lib/simple-tree/api/customTree.js +79 -19
  328. package/lib/simple-tree/api/customTree.js.map +1 -1
  329. package/lib/simple-tree/api/getJsonSchema.d.ts +7 -2
  330. package/lib/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  331. package/lib/simple-tree/api/getJsonSchema.js +1 -0
  332. package/lib/simple-tree/api/getJsonSchema.js.map +1 -1
  333. package/lib/simple-tree/api/index.d.ts +2 -1
  334. package/lib/simple-tree/api/index.d.ts.map +1 -1
  335. package/lib/simple-tree/api/index.js +2 -1
  336. package/lib/simple-tree/api/index.js.map +1 -1
  337. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +1 -1
  338. package/lib/simple-tree/api/schemaCreationUtilities.js +1 -1
  339. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  340. package/lib/simple-tree/api/schemaFactory.d.ts +9 -6
  341. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  342. package/lib/simple-tree/api/schemaFactory.js +6 -6
  343. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  344. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +13 -17
  345. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  346. package/lib/simple-tree/api/schemaFactoryAlpha.js +22 -26
  347. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  348. package/lib/simple-tree/api/schemaFactoryBeta.d.ts +20 -0
  349. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -0
  350. package/lib/simple-tree/api/schemaFactoryBeta.js +22 -0
  351. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -0
  352. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +5 -3
  353. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  354. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  355. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +0 -2
  356. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  357. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +6 -3
  358. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  359. package/lib/simple-tree/api/transactionTypes.d.ts +1 -0
  360. package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
  361. package/lib/simple-tree/api/transactionTypes.js.map +1 -1
  362. package/lib/simple-tree/api/tree.d.ts +68 -74
  363. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  364. package/lib/simple-tree/api/tree.js.map +1 -1
  365. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  366. package/lib/simple-tree/api/verboseTree.js +4 -4
  367. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  368. package/lib/simple-tree/core/simpleNodeSchemaBase.d.ts +6 -0
  369. package/lib/simple-tree/core/simpleNodeSchemaBase.d.ts.map +1 -1
  370. package/lib/simple-tree/core/simpleNodeSchemaBase.js.map +1 -1
  371. package/lib/simple-tree/fieldSchema.d.ts +3 -4
  372. package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
  373. package/lib/simple-tree/fieldSchema.js +0 -3
  374. package/lib/simple-tree/fieldSchema.js.map +1 -1
  375. package/lib/simple-tree/index.d.ts +1 -1
  376. package/lib/simple-tree/index.d.ts.map +1 -1
  377. package/lib/simple-tree/index.js +1 -1
  378. package/lib/simple-tree/index.js.map +1 -1
  379. package/lib/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
  380. package/lib/simple-tree/node-kinds/record/recordNode.js +2 -3
  381. package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  382. package/lib/simple-tree/simpleSchema.d.ts +12 -0
  383. package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
  384. package/lib/simple-tree/simpleSchema.js.map +1 -1
  385. package/lib/simple-tree/toStoredSchema.d.ts +0 -3
  386. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  387. package/lib/simple-tree/toStoredSchema.js +0 -3
  388. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  389. package/lib/tableSchema.d.ts +11 -80
  390. package/lib/tableSchema.d.ts.map +1 -1
  391. package/lib/tableSchema.js +201 -118
  392. package/lib/tableSchema.js.map +1 -1
  393. package/lib/treeFactory.d.ts +1 -2
  394. package/lib/treeFactory.d.ts.map +1 -1
  395. package/lib/treeFactory.js +1 -2
  396. package/lib/treeFactory.js.map +1 -1
  397. package/lib/tsdoc-metadata.json +1 -1
  398. package/lib/util/breakable.d.ts.map +1 -1
  399. package/lib/util/breakable.js +7 -1
  400. package/lib/util/breakable.js.map +1 -1
  401. package/package.json +28 -28
  402. package/src/codec/codec.ts +52 -7
  403. package/src/codec/index.ts +4 -0
  404. package/src/external-utilities/index.ts +1 -1
  405. package/src/external-utilities/typeboxValidator.ts +7 -1
  406. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +38 -4
  407. package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +10 -3
  408. package/src/feature-libraries/chunked-forest/codec/codecs.ts +96 -8
  409. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +123 -19
  410. package/src/feature-libraries/chunked-forest/codec/format.ts +11 -0
  411. package/src/feature-libraries/chunked-forest/codec/index.ts +4 -0
  412. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +28 -3
  413. package/src/feature-libraries/chunked-forest/index.ts +2 -0
  414. package/src/feature-libraries/forest-summary/codec.ts +3 -0
  415. package/src/feature-libraries/forest-summary/forestSummarizer.ts +118 -50
  416. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +511 -0
  417. package/src/feature-libraries/forest-summary/index.ts +1 -1
  418. package/src/feature-libraries/index.ts +5 -1
  419. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +8 -4
  420. package/src/feature-libraries/treeCompressionUtils.ts +19 -0
  421. package/src/index.ts +6 -1
  422. package/src/packageVersion.ts +1 -1
  423. package/src/shared-tree/schematizingTreeView.ts +1 -1
  424. package/src/shared-tree/sharedTree.ts +37 -4
  425. package/src/shared-tree/sharedTreeChangeFamily.ts +2 -2
  426. package/src/shared-tree/tree.ts +3 -0
  427. package/src/shared-tree/treeAlpha.ts +10 -11
  428. package/src/shared-tree/treeCheckout.ts +3 -2
  429. package/src/shared-tree-core/sharedTreeCore.ts +17 -0
  430. package/src/sharedTreeAttributes.ts +2 -2
  431. package/src/simple-tree/api/conciseTree.ts +2 -1
  432. package/src/simple-tree/api/customTree.ts +102 -32
  433. package/src/simple-tree/api/getJsonSchema.ts +7 -2
  434. package/src/simple-tree/api/index.ts +3 -0
  435. package/src/simple-tree/api/schemaCreationUtilities.ts +1 -1
  436. package/src/simple-tree/api/schemaFactory.ts +21 -14
  437. package/src/simple-tree/api/schemaFactoryAlpha.ts +29 -30
  438. package/src/simple-tree/api/schemaFactoryBeta.ts +28 -0
  439. package/src/simple-tree/api/schemaFactoryRecursive.ts +41 -40
  440. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +7 -3
  441. package/src/simple-tree/api/transactionTypes.ts +1 -0
  442. package/src/simple-tree/api/tree.ts +75 -81
  443. package/src/simple-tree/api/verboseTree.ts +42 -39
  444. package/src/simple-tree/core/simpleNodeSchemaBase.ts +6 -0
  445. package/src/simple-tree/fieldSchema.ts +3 -4
  446. package/src/simple-tree/index.ts +3 -0
  447. package/src/simple-tree/node-kinds/record/recordNode.ts +2 -3
  448. package/src/simple-tree/simpleSchema.ts +12 -0
  449. package/src/simple-tree/toStoredSchema.ts +0 -3
  450. package/src/tableSchema.ts +261 -243
  451. package/src/treeFactory.ts +1 -2
  452. package/src/util/breakable.ts +9 -1
@@ -11,6 +11,7 @@ import {
11
11
  type FieldKey,
12
12
  type FieldKindIdentifier,
13
13
  type ITreeCursorSynchronous,
14
+ type TreeChunk,
14
15
  type TreeFieldStoredSchema,
15
16
  type TreeNodeSchemaIdentifier,
16
17
  type Value,
@@ -35,9 +36,10 @@ import {
35
36
  SpecialField,
36
37
  version,
37
38
  } from "./format.js";
39
+ import type { ChunkReferenceId, IncrementalEncoder } from "./codecs.js";
38
40
 
39
41
  /**
40
- * Encode data from `FieldBatch` into an `EncodedChunk`.
42
+ * Encode data from `FieldBatch` into an `EncodedFieldBatch`.
41
43
  *
42
44
  * Optimized for encoded size and encoding performance.
43
45
  *
@@ -347,22 +349,48 @@ export class InlineArrayEncoder
347
349
  }
348
350
  }
349
351
 
352
+ /**
353
+ * Encodes the shape for a nested array as {@link EncodedNestedArray} shape.
354
+ */
355
+ export class NestedArrayShape extends ShapeGeneric<EncodedChunkShape> {
356
+ /**
357
+ * @param innerShape - The shape of each item in this nested array.
358
+ */
359
+ public constructor(public readonly innerShape: Shape) {
360
+ super();
361
+ }
362
+
363
+ public encodeShape(
364
+ identifiers: DeduplicationTable<string>,
365
+ shapes: DeduplicationTable<Shape>,
366
+ ): EncodedChunkShape {
367
+ const shape: EncodedNestedArrayShape =
368
+ shapes.valueToIndex.get(this.innerShape) ??
369
+ fail(0xb4f /* index for shape not found in table */);
370
+ return {
371
+ a: shape,
372
+ };
373
+ }
374
+
375
+ public countReferencedShapesAndIdentifiers(
376
+ identifiers: Counter<string>,
377
+ shapeDiscovered: (shape: Shape) => void,
378
+ ): void {
379
+ shapeDiscovered(this.innerShape);
380
+ }
381
+ }
382
+
350
383
  /**
351
384
  * Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.
352
385
  * @remarks
353
- * The fact this is also a Shape is an implementation detail of the encoder: that allows the shape it uses to be itself,
386
+ * The fact this is also exposes a Shape is an implementation detail: it allows the shape it uses to be itself
354
387
  * which is an easy way to keep all the related code together without extra objects.
355
388
  */
356
- export class NestedArrayEncoder
357
- extends ShapeGeneric<EncodedChunkShape>
358
- implements FieldEncoder
359
- {
360
- public readonly shape: Shape;
361
-
362
- public constructor(public readonly inner: NodeEncoder) {
363
- super();
364
- this.shape = this;
365
- }
389
+ export class NestedArrayEncoder implements FieldEncoder {
390
+ public constructor(
391
+ public readonly innerEncoder: NodeEncoder,
392
+ public readonly shape: NestedArrayShape = new NestedArrayShape(innerEncoder.shape),
393
+ ) {}
366
394
 
367
395
  public encodeField(
368
396
  cursor: ITreeCursorSynchronous,
@@ -374,7 +402,7 @@ export class NestedArrayEncoder
374
402
  const length = cursor.getFieldLength();
375
403
  forEachNode(cursor, () => {
376
404
  const before = buffer.length;
377
- this.inner.encodeNode(cursor, context, buffer);
405
+ this.innerEncoder.encodeNode(cursor, context, buffer);
378
406
  allNonZeroSize &&= buffer.length - before !== 0;
379
407
  });
380
408
  if (buffer.length === 0) {
@@ -389,27 +417,77 @@ export class NestedArrayEncoder
389
417
  outputBuffer.push(buffer);
390
418
  }
391
419
  }
420
+ }
421
+
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}.
426
+ */
427
+ 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
+ }
392
446
 
393
447
  public encodeShape(
394
448
  identifiers: DeduplicationTable<string>,
395
449
  shapes: DeduplicationTable<Shape>,
396
450
  ): EncodedChunkShape {
397
- const shape: EncodedNestedArrayShape =
398
- shapes.valueToIndex.get(this.inner.shape) ??
399
- fail(0xb4f /* index for shape not found in table */);
400
451
  return {
401
- a: shape,
452
+ e: 0 /* EncodedIncrementalChunkShape */,
402
453
  };
403
454
  }
404
455
 
405
456
  public countReferencedShapesAndIdentifiers(
406
457
  identifiers: Counter<string>,
407
458
  shapeDiscovered: (shape: Shape) => void,
408
- ): void {
409
- shapeDiscovered(this.inner.shape);
459
+ ): void {}
460
+
461
+ public get shape(): this {
462
+ return this;
410
463
  }
411
464
  }
412
465
 
466
+ /**
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.
470
+ */
471
+ export const incrementalFieldEncoder: FieldEncoder = {
472
+ encodeField(
473
+ cursor: ITreeCursorSynchronous,
474
+ context: EncoderContext,
475
+ outputBuffer: BufferFormat,
476
+ ): void {
477
+ assert(
478
+ context.shouldEncodeIncrementally,
479
+ 0xc2a /* incremental encoding must be enabled to use IncrementalFieldShape */,
480
+ );
481
+
482
+ const chunkReferenceIds = context.encodeIncrementalField(cursor, (chunk: TreeChunk) =>
483
+ IncrementalChunkShape.encodeChunk(chunk, context),
484
+ );
485
+ outputBuffer.push(chunkReferenceIds);
486
+ },
487
+
488
+ shape: new NestedArrayShape(new IncrementalChunkShape() /* innerShape */),
489
+ };
490
+
413
491
  /**
414
492
  * Encode `value` with `shape` into `outputBuffer`.
415
493
  *
@@ -448,6 +526,7 @@ export function encodeValue(
448
526
  /**
449
527
  * Provides common contextual information during encoding, like schema and policy settings.
450
528
  * Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.
529
+ * @remarks
451
530
  * To avoid Shape duplication, any Shapes used in the encoding should either be:
452
531
  * - Singletons defined in a static scope.
453
532
  * - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.
@@ -461,6 +540,7 @@ export class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
461
540
  private readonly fieldEncoderFromPolicy: FieldEncoderPolicy,
462
541
  public readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
463
542
  public readonly idCompressor: IIdCompressor,
543
+ private readonly incrementalEncoder: IncrementalEncoder | undefined,
464
544
  ) {}
465
545
 
466
546
  public nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder {
@@ -476,6 +556,30 @@ export class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
476
556
  public nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder {
477
557
  return getOrCreate(this.nestedArrayEncoders, inner, () => new NestedArrayEncoder(inner));
478
558
  }
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
+ }
479
583
  }
480
584
 
481
585
  export interface NodeEncodeBuilder {
@@ -47,6 +47,12 @@ export const EncodedInlineArrayShape = Type.Object(
47
47
  */
48
48
  export const EncodedAnyShape = Type.Literal(0);
49
49
 
50
+ /**
51
+ * Encoded content is a {@link ChunkReferenceId}.
52
+ * This represents the shape of a chunk that is encoded separately and is referenced by its {@link ChunkReferenceId}.
53
+ */
54
+ export const EncodedIncrementalChunkShape = Type.Literal(0);
55
+
50
56
  /**
51
57
  * Content of the encoded field is specified by the Shape referenced by the ShapeIndex.
52
58
  * This is a tuple for conciseness.
@@ -185,6 +191,10 @@ export const EncodedChunkShape = Type.Object(
185
191
  * {@link EncodedAnyShape} union member.
186
192
  */
187
193
  d: Type.Optional(EncodedAnyShape),
194
+ /**
195
+ * {@link EncodedIncrementalChunkShape} union member.
196
+ */
197
+ e: Type.Optional(EncodedIncrementalChunkShape),
188
198
  },
189
199
  unionOptions,
190
200
  );
@@ -195,6 +205,7 @@ export type EncodedNestedArrayShape = Static<typeof EncodedNestedArrayShape>;
195
205
  export type EncodedInlineArrayShape = Static<typeof EncodedInlineArrayShape>;
196
206
  export type EncodedNodeShape = Static<typeof EncodedNodeShape>;
197
207
  export type EncodedAnyShape = Static<typeof EncodedAnyShape>;
208
+ export type EncodedIncrementalChunkShape = Static<typeof EncodedIncrementalChunkShape>;
198
209
 
199
210
  export const EncodedFieldBatch = EncodedFieldBatchGeneric(version, EncodedChunkShape);
200
211
  export type EncodedFieldBatch = Static<typeof EncodedFieldBatch>;
@@ -10,4 +10,8 @@ export {
10
10
  makeFieldBatchCodec,
11
11
  type FieldBatchEncodingContext,
12
12
  fluidVersionToFieldBatchCodecWriteVersion,
13
+ type IncrementalEncoderDecoder,
14
+ type IncrementalEncoder,
15
+ type IncrementalDecoder,
16
+ type ChunkReferenceId,
13
17
  } from "./codecs.js";
@@ -16,6 +16,7 @@ import {
16
16
  ValueSchema,
17
17
  Multiplicity,
18
18
  identifierFieldKindIdentifier,
19
+ type FieldKey,
19
20
  } from "../../../core/index.js";
20
21
  import type { FullSchemaPolicy } from "../../modular-schema/index.js";
21
22
 
@@ -28,13 +29,19 @@ import {
28
29
  anyNodeEncoder,
29
30
  asFieldEncoder,
30
31
  compressedEncode,
32
+ incrementalFieldEncoder,
31
33
  } from "./compressedEncode.js";
32
34
  import type { FieldBatch } from "./fieldBatch.js";
33
35
  import { type EncodedFieldBatch, type EncodedValueShape, SpecialField } from "./format.js";
36
+ import type { IncrementalEncoder } from "./codecs.js";
34
37
  import { NodeShapeBasedEncoder } from "./nodeEncoder.js";
35
38
 
36
39
  /**
37
40
  * Encode data from `fieldBatch` in into an `EncodedChunk`.
41
+ * @remarks
42
+ * If `incrementalEncoder` is provided,
43
+ * fields that support incremental encoding will encode their chunks separately via the `incrementalEncoder`.
44
+ * See {@link IncrementalEncoder} for more details.
38
45
  *
39
46
  * Optimized for encoded size and encoding performance.
40
47
  * TODO: This function should eventually also take in the root FieldSchema to more efficiently compress the nodes.
@@ -44,22 +51,28 @@ export function schemaCompressedEncode(
44
51
  policy: FullSchemaPolicy,
45
52
  fieldBatch: FieldBatch,
46
53
  idCompressor: IIdCompressor,
54
+ incrementalEncoder?: IncrementalEncoder,
47
55
  ): EncodedFieldBatch {
48
- return compressedEncode(fieldBatch, buildContext(schema, policy, idCompressor));
56
+ return compressedEncode(
57
+ fieldBatch,
58
+ buildContext(schema, policy, idCompressor, incrementalEncoder),
59
+ );
49
60
  }
50
61
 
51
62
  export function buildContext(
52
63
  storedSchema: StoredSchemaCollection,
53
64
  policy: FullSchemaPolicy,
54
65
  idCompressor: IIdCompressor,
66
+ incrementalEncoder?: IncrementalEncoder,
55
67
  ): EncoderContext {
56
68
  const context: EncoderContext = new EncoderContext(
57
69
  (fieldBuilder: FieldEncodeBuilder, schemaName: TreeNodeSchemaIdentifier) =>
58
- getNodeEncoder(fieldBuilder, storedSchema, schemaName),
70
+ getNodeEncoder(fieldBuilder, storedSchema, schemaName, incrementalEncoder),
59
71
  (nodeBuilder: NodeEncodeBuilder, fieldSchema: TreeFieldStoredSchema) =>
60
72
  getFieldEncoder(nodeBuilder, fieldSchema, context, storedSchema),
61
73
  policy.fieldKinds,
62
74
  idCompressor,
75
+ incrementalEncoder,
63
76
  );
64
77
  return context;
65
78
  }
@@ -111,6 +124,7 @@ export function getNodeEncoder(
111
124
  fieldBuilder: FieldEncodeBuilder,
112
125
  storedSchema: StoredSchemaCollection,
113
126
  schemaName: TreeNodeSchemaIdentifier,
127
+ incrementalEncoder?: IncrementalEncoder,
114
128
  ): NodeShapeBasedEncoder {
115
129
  const schema =
116
130
  storedSchema.nodeSchema.get(schemaName) ?? fail(0xb53 /* missing node schema */);
@@ -120,9 +134,20 @@ export function getNodeEncoder(
120
134
  // consider moving some optional and sequence fields to extra fields if they are commonly empty
121
135
  // to reduce encoded size.
122
136
 
137
+ const shouldEncodeFieldIncrementallyLocal = (
138
+ nodeIdentifier: TreeNodeSchemaIdentifier,
139
+ fieldKey: FieldKey,
140
+ ): boolean =>
141
+ incrementalEncoder?.shouldEncodeFieldIncrementally(nodeIdentifier, fieldKey) ?? false;
123
142
  const objectNodeFields: KeyedFieldEncoder[] = [];
124
143
  for (const [key, field] of schema.objectNodeFields ?? []) {
125
- objectNodeFields.push({ key, encoder: fieldBuilder.fieldEncoderFromSchema(field) });
144
+ const fieldEncoder = shouldEncodeFieldIncrementallyLocal(schemaName, key)
145
+ ? incrementalFieldEncoder
146
+ : fieldBuilder.fieldEncoderFromSchema(field);
147
+ objectNodeFields.push({
148
+ key,
149
+ encoder: fieldEncoder,
150
+ });
126
151
  }
127
152
 
128
153
  const shape = new NodeShapeBasedEncoder(schemaName, false, objectNodeFields, undefined);
@@ -21,5 +21,7 @@ export {
21
21
  makeFieldBatchCodec,
22
22
  type FieldBatchEncodingContext,
23
23
  fluidVersionToFieldBatchCodecWriteVersion,
24
+ type IncrementalEncoderDecoder,
25
+ type ChunkReferenceId,
24
26
  } from "./codec/index.js";
25
27
  export { emptyChunk } from "./emptyChunk.js";
@@ -26,6 +26,9 @@ export function makeForestSummarizerCodec(
26
26
  fieldBatchCodec: FieldBatchCodec,
27
27
  ): ForestCodec {
28
28
  const inner = fieldBatchCodec;
29
+ // TODO: AB#41865
30
+ // This needs to be updated to support multiple versions.
31
+ // The second version will be used to enable incremental summarization.
29
32
  return makeVersionedValidatedCodec(options, new Set([1]), Format, {
30
33
  encode: (data: FieldSet, context: FieldBatchEncodingContext): Format => {
31
34
  const keys: FieldKey[] = [];
@@ -12,7 +12,6 @@ import type {
12
12
  ISummaryTreeWithStats,
13
13
  ITelemetryContext,
14
14
  } from "@fluidframework/runtime-definitions/internal";
15
- import { createSingleBlobSummary } from "@fluidframework/shared-object-base/internal";
16
15
 
17
16
  import type { CodecWriteOptions } from "../../codec/index.js";
18
17
  import {
@@ -24,6 +23,7 @@ import {
24
23
  type ITreeSubscriptionCursor,
25
24
  type RevisionTagCodec,
26
25
  TreeNavigationResult,
26
+ type TreeNodeSchemaIdentifier,
27
27
  applyDelta,
28
28
  forEachField,
29
29
  makeDetachedFieldIndex,
@@ -33,25 +33,37 @@ import type {
33
33
  SummaryElementParser,
34
34
  SummaryElementStringifier,
35
35
  } from "../../shared-tree-core/index.js";
36
- import { idAllocatorFromMaxId } from "../../util/index.js";
37
- import { chunkFieldSingle, defaultChunkPolicy } from "../chunked-forest/index.js";
36
+ import { idAllocatorFromMaxId, type JsonCompatible } from "../../util/index.js";
37
+ // eslint-disable-next-line import/no-internal-modules
38
+ import { chunkFieldSingle, defaultChunkPolicy } from "../chunked-forest/chunkTree.js";
38
39
  import type { FieldBatchCodec, FieldBatchEncodingContext } from "../chunked-forest/index.js";
39
40
 
40
41
  import { type ForestCodec, makeForestSummarizerCodec } from "./codec.js";
41
- import type { Format } from "./format.js";
42
+ import {
43
+ ForestIncrementalSummaryBehavior,
44
+ ForestIncrementalSummaryBuilder,
45
+ forestSummaryContentKey,
46
+ } from "./incrementalSummaryBuilder.js";
47
+ import { TreeCompressionStrategyExtended } from "../treeCompressionUtils.js";
48
+ import type { IFluidHandle } from "@fluidframework/core-interfaces";
49
+
42
50
  /**
43
- * The storage key for the blob in the summary containing tree data
51
+ * The key for the tree that contains the overall forest's summary tree.
52
+ * This tree is added by the parent of the forest summarizer.
53
+ * See {@link ForestIncrementalSummaryBuilder} for details on the summary structure.
44
54
  */
45
- export const treeBlobKey = "ForestTree";
55
+ export const forestSummaryKey = "Forest";
46
56
 
47
57
  /**
48
58
  * Provides methods for summarizing and loading a forest.
49
59
  */
50
60
  export class ForestSummarizer implements Summarizable {
51
- public readonly key = "Forest";
61
+ public readonly key = forestSummaryKey;
52
62
 
53
63
  private readonly codec: ForestCodec;
54
64
 
65
+ private readonly incrementalSummaryBuilder: ForestIncrementalSummaryBuilder;
66
+
55
67
  /**
56
68
  * @param encoderContext - The schema if provided here must be mutated by the caller to keep it up to date.
57
69
  */
@@ -62,19 +74,45 @@ export class ForestSummarizer implements Summarizable {
62
74
  private readonly encoderContext: FieldBatchEncodingContext,
63
75
  options: CodecWriteOptions,
64
76
  private readonly idCompressor: IIdCompressor,
77
+ shouldEncodeFieldIncrementally?: (
78
+ nodeIdentifier: TreeNodeSchemaIdentifier,
79
+ fieldKey: FieldKey,
80
+ ) => boolean,
65
81
  ) {
66
82
  // TODO: this should take in CodecWriteOptions, and use it to pick the write version.
67
83
  this.codec = makeForestSummarizerCodec(options, fieldBatchCodec);
84
+
85
+ const shouldEncodeFieldIncrementallyLocal = (
86
+ nodeIdentifier: TreeNodeSchemaIdentifier,
87
+ fieldKey: FieldKey,
88
+ ): boolean => shouldEncodeFieldIncrementally?.(nodeIdentifier, fieldKey) ?? false;
89
+ this.incrementalSummaryBuilder = new ForestIncrementalSummaryBuilder(
90
+ encoderContext.encodeType ===
91
+ TreeCompressionStrategyExtended.CompressedIncremental /* enableIncrementalSummary */,
92
+ (cursor: ITreeCursorSynchronous) => this.forest.chunkField(cursor),
93
+ shouldEncodeFieldIncrementallyLocal,
94
+ );
68
95
  }
69
96
 
70
97
  /**
71
- * Synchronous monolithic summarization of tree content.
98
+ * Summarization of the forest's tree content.
99
+ * @returns a summary tree containing the forest's tree content.
100
+ * @remarks
101
+ * If incremental summary is disabled, all the content will be added to a single summary blob.
102
+ * If incremental summary is enabled, the summary will be a tree.
103
+ * See {@link ForestIncrementalSummaryBuilder} for details of what this tree looks like.
72
104
  *
73
105
  * TODO: when perf matters, this should be replaced with a chunked async version using a binary format.
74
- *
75
- * @returns a snapshot of the forest's tree as a string.
76
106
  */
77
- private getTreeString(stringify: SummaryElementStringifier): string {
107
+ public summarize(props: {
108
+ stringify: SummaryElementStringifier;
109
+ fullTree?: boolean;
110
+ trackState?: boolean;
111
+ telemetryContext?: ITelemetryContext;
112
+ incrementalSummaryContext?: IExperimentalIncrementalSummaryContext;
113
+ }): ISummaryTreeWithStats {
114
+ const { stringify, fullTree = false, incrementalSummaryContext } = props;
115
+
78
116
  const rootCursor = this.forest.getCursorAboveDetachedFields();
79
117
  const fieldMap: Map<FieldKey, ITreeCursorSynchronous & ITreeSubscriptionCursor> =
80
118
  new Map();
@@ -89,55 +127,85 @@ export class ForestSummarizer implements Summarizable {
89
127
  );
90
128
  fieldMap.set(key, innerCursor as ITreeCursorSynchronous & ITreeSubscriptionCursor);
91
129
  });
92
- const encoded = this.codec.encode(fieldMap, this.encoderContext);
93
130
 
131
+ // Let the incremental summary builder know that we are starting a new summary.
132
+ // It returns whether incremental encoding is enabled.
133
+ const incrementalSummaryBehavior = this.incrementalSummaryBuilder.startSummary({
134
+ fullTree,
135
+ incrementalSummaryContext,
136
+ stringify,
137
+ });
138
+ const encoderContext: FieldBatchEncodingContext = {
139
+ ...this.encoderContext,
140
+ incrementalEncoderDecoder:
141
+ incrementalSummaryBehavior === ForestIncrementalSummaryBehavior.Incremental
142
+ ? this.incrementalSummaryBuilder
143
+ : undefined,
144
+ };
145
+ const encoded = this.codec.encode(fieldMap, encoderContext);
94
146
  fieldMap.forEach((value) => value.free());
95
- return stringify(encoded);
96
- }
97
147
 
98
- public summarize(props: {
99
- stringify: SummaryElementStringifier;
100
- fullTree?: boolean;
101
- trackState?: boolean;
102
- telemetryContext?: ITelemetryContext;
103
- incrementalSummaryContext?: IExperimentalIncrementalSummaryContext;
104
- }): ISummaryTreeWithStats {
105
- return createSingleBlobSummary(treeBlobKey, this.getTreeString(props.stringify));
148
+ return this.incrementalSummaryBuilder.completeSummary({
149
+ incrementalSummaryContext,
150
+ forestSummaryContent: stringify(encoded),
151
+ });
106
152
  }
107
153
 
108
154
  public async load(
109
155
  services: IChannelStorageService,
110
156
  parse: SummaryElementParser,
111
157
  ): Promise<void> {
112
- if (await services.contains(treeBlobKey)) {
113
- const treeBuffer = await services.readBlob(treeBlobKey);
158
+ // The contents of the top-level forest must be present under a summary blob named `forestSummaryContentKey`.
159
+ // If the summary was generated as `ForestIncrementalSummaryBehavior.SingleBlob`, this blob will contain all
160
+ // of forest's contents.
161
+ // If the summary was generated as `ForestIncrementalSummaryBehavior.Incremental`, this blob will contain only
162
+ // the top-level forest node's contents.
163
+ // The contents of the incremental chunks will be in separate tree nodes and will be read later during decoding.
164
+ assert(
165
+ await services.contains(forestSummaryContentKey),
166
+ 0xc21 /* Forest summary content missing in snapshot */,
167
+ );
168
+
169
+ const readAndParseBlob = async <T extends JsonCompatible<IFluidHandle>>(
170
+ id: string,
171
+ ): Promise<T> => {
172
+ const treeBuffer = await services.readBlob(id);
114
173
  const treeBufferString = bufferToString(treeBuffer, "utf8");
115
- // TODO: this code is parsing data without an optional validator, this should be defined in a typebox schema as part of the
116
- // forest summary format.
117
- const fields = this.codec.decode(parse(treeBufferString) as Format, this.encoderContext);
118
- const allocator = idAllocatorFromMaxId();
119
- const fieldChanges: [FieldKey, DeltaFieldChanges][] = [];
120
- const build: DeltaDetachedNodeBuild[] = [];
121
- for (const [fieldKey, field] of fields) {
122
- const chunked = chunkFieldSingle(field, {
123
- policy: defaultChunkPolicy,
124
- idCompressor: this.idCompressor,
125
- });
126
- const buildId = { minor: allocator.allocate(chunked.topLevelLength) };
127
- build.push({
128
- id: buildId,
129
- trees: chunked,
130
- });
131
- fieldChanges.push([fieldKey, [{ count: chunked.topLevelLength, attach: buildId }]]);
132
- }
133
-
134
- assert(this.forest.isEmpty, 0x797 /* forest must be empty */);
135
- applyDelta(
136
- { build, fields: new Map(fieldChanges) },
137
- undefined,
138
- this.forest,
139
- makeDetachedFieldIndex("init", this.revisionTagCodec, this.idCompressor),
140
- );
174
+ return parse(treeBufferString) as T;
175
+ };
176
+
177
+ // Load the incremental summary builder so that it can download any incremental chunks in the
178
+ // snapshot.
179
+ await this.incrementalSummaryBuilder.load(services, readAndParseBlob);
180
+
181
+ // TODO: this code is parsing data without an optional validator, this should be defined in a typebox schema as part of the
182
+ // forest summary format.
183
+ const fields = this.codec.decode(await readAndParseBlob(forestSummaryContentKey), {
184
+ ...this.encoderContext,
185
+ incrementalEncoderDecoder: this.incrementalSummaryBuilder,
186
+ });
187
+ const allocator = idAllocatorFromMaxId();
188
+ const fieldChanges: [FieldKey, DeltaFieldChanges][] = [];
189
+ const build: DeltaDetachedNodeBuild[] = [];
190
+ for (const [fieldKey, field] of fields) {
191
+ const chunked = chunkFieldSingle(field, {
192
+ policy: defaultChunkPolicy,
193
+ idCompressor: this.idCompressor,
194
+ });
195
+ const buildId = { minor: allocator.allocate(chunked.topLevelLength) };
196
+ build.push({
197
+ id: buildId,
198
+ trees: chunked,
199
+ });
200
+ fieldChanges.push([fieldKey, [{ count: chunked.topLevelLength, attach: buildId }]]);
141
201
  }
202
+
203
+ assert(this.forest.isEmpty, 0x797 /* forest must be empty */);
204
+ applyDelta(
205
+ { build, fields: new Map(fieldChanges) },
206
+ undefined,
207
+ this.forest,
208
+ makeDetachedFieldIndex("init", this.revisionTagCodec, this.idCompressor),
209
+ );
142
210
  }
143
211
  }