@fluidframework/tree 2.92.0 → 2.100.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 (366) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/INCREMENTAL_SUMMARY.md +89 -0
  3. package/README.md +7 -1
  4. package/api-report/tree.alpha.api.md +60 -29
  5. package/api-report/tree.beta.api.md +41 -12
  6. package/api-report/tree.legacy.beta.api.md +41 -12
  7. package/dist/api.d.ts +6 -1
  8. package/dist/api.d.ts.map +1 -1
  9. package/dist/api.js.map +1 -1
  10. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  11. package/dist/core/tree/anchorSet.js +21 -0
  12. package/dist/core/tree/anchorSet.js.map +1 -1
  13. package/dist/entrypoints/alpha.d.ts +1 -1
  14. package/dist/entrypoints/alpha.d.ts.map +1 -1
  15. package/dist/entrypoints/alpha.js +4 -4
  16. package/dist/entrypoints/alpha.js.map +1 -1
  17. package/dist/entrypoints/beta.d.ts +1 -1
  18. package/dist/entrypoints/beta.d.ts.map +1 -1
  19. package/dist/entrypoints/beta.js +3 -1
  20. package/dist/entrypoints/beta.js.map +1 -1
  21. package/dist/entrypoints/legacy.d.ts +1 -1
  22. package/dist/entrypoints/legacy.d.ts.map +1 -1
  23. package/dist/entrypoints/legacy.js +3 -1
  24. package/dist/entrypoints/legacy.js.map +1 -1
  25. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +25 -1
  26. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  27. package/dist/feature-libraries/chunked-forest/basicChunk.js +71 -18
  28. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  29. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +2 -2
  30. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  31. package/dist/feature-libraries/chunked-forest/chunkTree.js +2 -1
  32. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  33. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +1 -1
  34. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  35. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/codec/codecs.js +1 -1
  37. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +1 -1
  39. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  40. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +1 -1
  41. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  42. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +1 -2
  43. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +0 -1
  45. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
  46. package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts +1 -1
  47. package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
  48. package/dist/feature-libraries/chunked-forest/codec/format/index.js +2 -1
  49. package/dist/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
  50. package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts +10 -2
  51. package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
  52. package/dist/feature-libraries/chunked-forest/codec/format/versions.js +15 -1
  53. package/dist/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
  54. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts +18 -5
  55. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  56. package/dist/feature-libraries/chunked-forest/uniformChunk.js +47 -19
  57. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  58. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +19 -0
  59. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  60. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +76 -22
  61. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  62. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts +1 -0
  63. package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  64. package/dist/feature-libraries/indexing/anchorTreeIndex.js +3 -1
  65. package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  66. package/dist/feature-libraries/indexing/types.d.ts +4 -3
  67. package/dist/feature-libraries/indexing/types.d.ts.map +1 -1
  68. package/dist/feature-libraries/indexing/types.js.map +1 -1
  69. package/dist/index.d.ts +1 -1
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/packageVersion.d.ts +1 -1
  73. package/dist/packageVersion.d.ts.map +1 -1
  74. package/dist/packageVersion.js +1 -1
  75. package/dist/packageVersion.js.map +1 -1
  76. package/dist/serializableDomainSchema.d.ts +5 -5
  77. package/dist/serializableDomainSchema.d.ts.map +1 -1
  78. package/dist/serializableDomainSchema.js.map +1 -1
  79. package/dist/shared-tree/treeAlpha.d.ts +6 -2
  80. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  81. package/dist/shared-tree/treeAlpha.js.map +1 -1
  82. package/dist/shared-tree/treeCheckout.d.ts +1 -1
  83. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  84. package/dist/simple-tree/api/discrepancies.js +4 -1
  85. package/dist/simple-tree/api/discrepancies.js.map +1 -1
  86. package/dist/simple-tree/api/identifierIndex.d.ts +2 -2
  87. package/dist/simple-tree/api/identifierIndex.js +1 -1
  88. package/dist/simple-tree/api/identifierIndex.js.map +1 -1
  89. package/dist/simple-tree/api/index.d.ts +2 -2
  90. package/dist/simple-tree/api/index.d.ts.map +1 -1
  91. package/dist/simple-tree/api/index.js +3 -2
  92. package/dist/simple-tree/api/index.js.map +1 -1
  93. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +47 -2
  94. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  95. package/dist/simple-tree/api/schemaFactoryAlpha.js +26 -1
  96. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  97. package/dist/simple-tree/api/simpleTreeIndex.d.ts +5 -5
  98. package/dist/simple-tree/api/simpleTreeIndex.js +1 -1
  99. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  100. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  101. package/dist/simple-tree/api/storedSchema.js +4 -1
  102. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  103. package/dist/simple-tree/api/treeAlpha.d.ts +70 -13
  104. package/dist/simple-tree/api/treeAlpha.d.ts.map +1 -1
  105. package/dist/simple-tree/api/treeAlpha.js.map +1 -1
  106. package/dist/simple-tree/api/treeChangeEvents.d.ts +1 -1
  107. package/dist/simple-tree/api/treeChangeEvents.js.map +1 -1
  108. package/dist/simple-tree/api/treeNodeApi.d.ts +60 -1
  109. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  110. package/dist/simple-tree/api/treeNodeApi.js +68 -6
  111. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  112. package/dist/simple-tree/core/toStored.d.ts +7 -0
  113. package/dist/simple-tree/core/toStored.d.ts.map +1 -1
  114. package/dist/simple-tree/core/toStored.js.map +1 -1
  115. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +17 -3
  116. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  117. package/dist/simple-tree/core/unhydratedFlexTree.js +114 -12
  118. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  119. package/dist/simple-tree/fieldSchema.d.ts +6 -1
  120. package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
  121. package/dist/simple-tree/fieldSchema.js +3 -0
  122. package/dist/simple-tree/fieldSchema.js.map +1 -1
  123. package/dist/simple-tree/index.d.ts +2 -2
  124. package/dist/simple-tree/index.d.ts.map +1 -1
  125. package/dist/simple-tree/index.js +4 -3
  126. package/dist/simple-tree/index.js.map +1 -1
  127. package/dist/simple-tree/node-kinds/index.d.ts +1 -1
  128. package/dist/simple-tree/node-kinds/index.d.ts.map +1 -1
  129. package/dist/simple-tree/node-kinds/index.js.map +1 -1
  130. package/dist/simple-tree/node-kinds/map/index.d.ts +1 -1
  131. package/dist/simple-tree/node-kinds/map/index.d.ts.map +1 -1
  132. package/dist/simple-tree/node-kinds/map/index.js.map +1 -1
  133. package/dist/simple-tree/node-kinds/map/mapNode.d.ts +13 -0
  134. package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  135. package/dist/simple-tree/node-kinds/map/mapNode.js +6 -1
  136. package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  137. package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts +6 -6
  138. package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
  139. package/dist/simple-tree/node-kinds/map/mapNodeTypes.js.map +1 -1
  140. package/dist/simple-tree/simpleSchema.d.ts +17 -0
  141. package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
  142. package/dist/simple-tree/simpleSchema.js.map +1 -1
  143. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  144. package/dist/simple-tree/toStoredSchema.js +23 -1
  145. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  146. package/dist/tableSchema.d.ts +4 -5
  147. package/dist/tableSchema.d.ts.map +1 -1
  148. package/dist/tableSchema.js +12 -23
  149. package/dist/tableSchema.js.map +1 -1
  150. package/dist/text/textDomain.d.ts.map +1 -1
  151. package/dist/text/textDomain.js +27 -0
  152. package/dist/text/textDomain.js.map +1 -1
  153. package/dist/text/textDomainFormatted.d.ts +4 -4
  154. package/dist/util/index.d.ts +1 -1
  155. package/dist/util/index.d.ts.map +1 -1
  156. package/dist/util/index.js +2 -3
  157. package/dist/util/index.js.map +1 -1
  158. package/dist/util/utils.d.ts +0 -1
  159. package/dist/util/utils.d.ts.map +1 -1
  160. package/dist/util/utils.js +1 -6
  161. package/dist/util/utils.js.map +1 -1
  162. package/docs/user-facing/isolated-declarations.md +147 -0
  163. package/eslint.config.mts +1 -1
  164. package/lib/api.d.ts +6 -1
  165. package/lib/api.d.ts.map +1 -1
  166. package/lib/api.js.map +1 -1
  167. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  168. package/lib/core/tree/anchorSet.js +21 -0
  169. package/lib/core/tree/anchorSet.js.map +1 -1
  170. package/lib/entrypoints/alpha.d.ts +1 -1
  171. package/lib/entrypoints/alpha.d.ts.map +1 -1
  172. package/lib/entrypoints/alpha.js +1 -1
  173. package/lib/entrypoints/alpha.js.map +1 -1
  174. package/lib/entrypoints/beta.d.ts +1 -1
  175. package/lib/entrypoints/beta.d.ts.map +1 -1
  176. package/lib/entrypoints/beta.js +1 -1
  177. package/lib/entrypoints/beta.js.map +1 -1
  178. package/lib/entrypoints/legacy.d.ts +1 -1
  179. package/lib/entrypoints/legacy.d.ts.map +1 -1
  180. package/lib/entrypoints/legacy.js +1 -1
  181. package/lib/entrypoints/legacy.js.map +1 -1
  182. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +25 -1
  183. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  184. package/lib/feature-libraries/chunked-forest/basicChunk.js +72 -19
  185. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  186. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +2 -2
  187. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  188. package/lib/feature-libraries/chunked-forest/chunkTree.js +2 -1
  189. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  190. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +2 -2
  191. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  192. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  193. package/lib/feature-libraries/chunked-forest/codec/codecs.js +2 -2
  194. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  195. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +1 -1
  196. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  197. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +2 -2
  198. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  199. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +1 -2
  200. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
  201. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js +0 -1
  202. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
  203. package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts +1 -1
  204. package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
  205. package/lib/feature-libraries/chunked-forest/codec/format/index.js +1 -1
  206. package/lib/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
  207. package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts +10 -2
  208. package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
  209. package/lib/feature-libraries/chunked-forest/codec/format/versions.js +13 -0
  210. package/lib/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
  211. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts +18 -5
  212. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  213. package/lib/feature-libraries/chunked-forest/uniformChunk.js +48 -20
  214. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  215. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +19 -0
  216. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  217. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +76 -22
  218. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  219. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts +1 -0
  220. package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
  221. package/lib/feature-libraries/indexing/anchorTreeIndex.js +3 -1
  222. package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  223. package/lib/feature-libraries/indexing/types.d.ts +4 -3
  224. package/lib/feature-libraries/indexing/types.d.ts.map +1 -1
  225. package/lib/feature-libraries/indexing/types.js.map +1 -1
  226. package/lib/index.d.ts +1 -1
  227. package/lib/index.d.ts.map +1 -1
  228. package/lib/index.js.map +1 -1
  229. package/lib/packageVersion.d.ts +1 -1
  230. package/lib/packageVersion.d.ts.map +1 -1
  231. package/lib/packageVersion.js +1 -1
  232. package/lib/packageVersion.js.map +1 -1
  233. package/lib/serializableDomainSchema.d.ts +5 -5
  234. package/lib/serializableDomainSchema.d.ts.map +1 -1
  235. package/lib/serializableDomainSchema.js +4 -1
  236. package/lib/serializableDomainSchema.js.map +1 -1
  237. package/lib/shared-tree/treeAlpha.d.ts +6 -2
  238. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  239. package/lib/shared-tree/treeAlpha.js.map +1 -1
  240. package/lib/shared-tree/treeCheckout.d.ts +1 -1
  241. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  242. package/lib/simple-tree/api/discrepancies.js +4 -1
  243. package/lib/simple-tree/api/discrepancies.js.map +1 -1
  244. package/lib/simple-tree/api/identifierIndex.d.ts +2 -2
  245. package/lib/simple-tree/api/identifierIndex.js +1 -1
  246. package/lib/simple-tree/api/identifierIndex.js.map +1 -1
  247. package/lib/simple-tree/api/index.d.ts +2 -2
  248. package/lib/simple-tree/api/index.d.ts.map +1 -1
  249. package/lib/simple-tree/api/index.js +1 -1
  250. package/lib/simple-tree/api/index.js.map +1 -1
  251. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +47 -2
  252. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  253. package/lib/simple-tree/api/schemaFactoryAlpha.js +28 -3
  254. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  255. package/lib/simple-tree/api/simpleTreeIndex.d.ts +5 -5
  256. package/lib/simple-tree/api/simpleTreeIndex.js +1 -1
  257. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  258. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  259. package/lib/simple-tree/api/storedSchema.js +4 -1
  260. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  261. package/lib/simple-tree/api/treeAlpha.d.ts +70 -13
  262. package/lib/simple-tree/api/treeAlpha.d.ts.map +1 -1
  263. package/lib/simple-tree/api/treeAlpha.js.map +1 -1
  264. package/lib/simple-tree/api/treeChangeEvents.d.ts +1 -1
  265. package/lib/simple-tree/api/treeChangeEvents.js.map +1 -1
  266. package/lib/simple-tree/api/treeNodeApi.d.ts +60 -1
  267. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  268. package/lib/simple-tree/api/treeNodeApi.js +66 -6
  269. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  270. package/lib/simple-tree/core/toStored.d.ts +7 -0
  271. package/lib/simple-tree/core/toStored.d.ts.map +1 -1
  272. package/lib/simple-tree/core/toStored.js.map +1 -1
  273. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +17 -3
  274. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  275. package/lib/simple-tree/core/unhydratedFlexTree.js +115 -13
  276. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  277. package/lib/simple-tree/fieldSchema.d.ts +6 -1
  278. package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
  279. package/lib/simple-tree/fieldSchema.js +3 -0
  280. package/lib/simple-tree/fieldSchema.js.map +1 -1
  281. package/lib/simple-tree/index.d.ts +2 -2
  282. package/lib/simple-tree/index.d.ts.map +1 -1
  283. package/lib/simple-tree/index.js +1 -1
  284. package/lib/simple-tree/index.js.map +1 -1
  285. package/lib/simple-tree/node-kinds/index.d.ts +1 -1
  286. package/lib/simple-tree/node-kinds/index.d.ts.map +1 -1
  287. package/lib/simple-tree/node-kinds/index.js.map +1 -1
  288. package/lib/simple-tree/node-kinds/map/index.d.ts +1 -1
  289. package/lib/simple-tree/node-kinds/map/index.d.ts.map +1 -1
  290. package/lib/simple-tree/node-kinds/map/index.js.map +1 -1
  291. package/lib/simple-tree/node-kinds/map/mapNode.d.ts +13 -0
  292. package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  293. package/lib/simple-tree/node-kinds/map/mapNode.js +6 -1
  294. package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  295. package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts +6 -6
  296. package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
  297. package/lib/simple-tree/node-kinds/map/mapNodeTypes.js.map +1 -1
  298. package/lib/simple-tree/simpleSchema.d.ts +17 -0
  299. package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
  300. package/lib/simple-tree/simpleSchema.js.map +1 -1
  301. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  302. package/lib/simple-tree/toStoredSchema.js +24 -2
  303. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  304. package/lib/tableSchema.d.ts +4 -5
  305. package/lib/tableSchema.d.ts.map +1 -1
  306. package/lib/tableSchema.js +12 -23
  307. package/lib/tableSchema.js.map +1 -1
  308. package/lib/text/textDomain.d.ts.map +1 -1
  309. package/lib/text/textDomain.js +29 -0
  310. package/lib/text/textDomain.js.map +1 -1
  311. package/lib/text/textDomainFormatted.d.ts +4 -4
  312. package/lib/tsdoc-metadata.json +1 -1
  313. package/lib/util/index.d.ts +1 -1
  314. package/lib/util/index.d.ts.map +1 -1
  315. package/lib/util/index.js +1 -1
  316. package/lib/util/index.js.map +1 -1
  317. package/lib/util/utils.d.ts +0 -1
  318. package/lib/util/utils.d.ts.map +1 -1
  319. package/lib/util/utils.js +0 -1
  320. package/lib/util/utils.js.map +1 -1
  321. package/package.json +32 -37
  322. package/src/api.ts +10 -0
  323. package/src/core/tree/anchorSet.ts +25 -0
  324. package/src/entrypoints/alpha.ts +20 -16
  325. package/src/entrypoints/beta.ts +7 -1
  326. package/src/entrypoints/legacy.ts +8 -10
  327. package/src/feature-libraries/chunked-forest/basicChunk.ts +76 -20
  328. package/src/feature-libraries/chunked-forest/chunkTree.ts +3 -2
  329. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +2 -2
  330. package/src/feature-libraries/chunked-forest/codec/codecs.ts +2 -1
  331. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +3 -2
  332. package/src/feature-libraries/chunked-forest/codec/format/formatGeneric.ts +0 -1
  333. package/src/feature-libraries/chunked-forest/codec/format/index.ts +1 -0
  334. package/src/feature-libraries/chunked-forest/codec/format/versions.ts +15 -0
  335. package/src/feature-libraries/chunked-forest/uniformChunk.ts +73 -21
  336. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +116 -31
  337. package/src/feature-libraries/indexing/anchorTreeIndex.ts +1 -0
  338. package/src/feature-libraries/indexing/types.ts +5 -3
  339. package/src/index.ts +4 -0
  340. package/src/packageVersion.ts +1 -1
  341. package/src/serializableDomainSchema.ts +6 -0
  342. package/src/shared-tree/treeAlpha.ts +6 -2
  343. package/src/simple-tree/api/discrepancies.ts +6 -1
  344. package/src/simple-tree/api/identifierIndex.ts +2 -2
  345. package/src/simple-tree/api/index.ts +4 -0
  346. package/src/simple-tree/api/schemaFactoryAlpha.ts +99 -3
  347. package/src/simple-tree/api/simpleTreeIndex.ts +6 -6
  348. package/src/simple-tree/api/storedSchema.ts +4 -1
  349. package/src/simple-tree/api/treeAlpha.ts +75 -12
  350. package/src/simple-tree/api/treeChangeEvents.ts +1 -1
  351. package/src/simple-tree/api/treeNodeApi.ts +101 -7
  352. package/src/simple-tree/core/toStored.ts +8 -0
  353. package/src/simple-tree/core/unhydratedFlexTree.ts +134 -10
  354. package/src/simple-tree/fieldSchema.ts +10 -0
  355. package/src/simple-tree/index.ts +5 -0
  356. package/src/simple-tree/node-kinds/index.ts +1 -0
  357. package/src/simple-tree/node-kinds/map/index.ts +1 -0
  358. package/src/simple-tree/node-kinds/map/mapNode.ts +20 -3
  359. package/src/simple-tree/node-kinds/map/mapNodeTypes.ts +6 -6
  360. package/src/simple-tree/simpleSchema.ts +20 -0
  361. package/src/simple-tree/toStoredSchema.ts +28 -1
  362. package/src/tableSchema.ts +16 -28
  363. package/src/text/textDomain.ts +68 -1
  364. package/src/util/index.ts +0 -1
  365. package/src/util/utils.ts +0 -2
  366. package/.mocharc.customBenchmarks.cjs +0 -25
@@ -50,10 +50,12 @@ interface ChunkLoadProperties {
50
50
  */
51
51
  readonly encodedContents: EncodedFieldBatchV2;
52
52
  /**
53
- * The path for this chunk's contents in the summary tree relative to the forest's summary tree.
54
- * This path is used to generate a summary handle for the chunk if it doesn't change between summaries.
53
+ * The reference ID of this chunk's parent in the summary tree, or `undefined` if this chunk is
54
+ * at the top level (directly under the forest summary tree).
55
+ * Stored here so that {@link ForestIncrementalSummaryBuilder.decodeIncrementalChunk} can
56
+ * reconstruct the correct {@link ChunkSummaryProperties} without re-parsing a path string.
55
57
  */
56
- readonly summaryPath: string;
58
+ readonly parentReferenceId: ChunkReferenceId | undefined;
57
59
  }
58
60
 
59
61
  /**
@@ -68,10 +70,20 @@ interface ChunkSummaryProperties {
68
70
  */
69
71
  readonly referenceId: ChunkReferenceId;
70
72
  /**
71
- * The path for this chunk's summary in the summary tree relative to the forest's summary tree.
72
- * This path is used to generate a summary handle for the chunk if it doesn't change between summaries.
73
+ * The reference ID of this chunk's parent in the summary tree, or `undefined` if this chunk
74
+ * is at the top level (has no incremental parent).
75
+ *
76
+ * @remarks
77
+ * Storing only the immediate parent (rather than the full path string) keeps every chunk's
78
+ * tracking entry correct even when an ancestor is re-encoded and receives a new reference ID.
79
+ * The full summary path is computed on demand by {@link ForestIncrementalSummaryBuilder.computeHandlePathInLatestSummary}
80
+ * by walking up the parent chain through {@link TrackedSummaryProperties.latestSummaryRefIdMap}.
81
+ *
82
+ * If a parent chunk is encoded as a handle in the current summary its reference ID is unchanged,
83
+ * so its children's `parentReferenceId` values copied forward by `completeSummary` remain valid
84
+ * without any additional update.
73
85
  */
74
- readonly summaryPath: string;
86
+ readonly parentReferenceId: ChunkReferenceId | undefined;
75
87
  }
76
88
 
77
89
  /**
@@ -109,6 +121,13 @@ interface TrackedSummaryProperties {
109
121
  * Serializes content (including {@link (IFluidHandle:interface)}s) for adding to a summary blob.
110
122
  */
111
123
  stringify: SummaryElementStringifier;
124
+ /**
125
+ * Reverse lookup map for the latest summary: maps each chunk's {@link ChunkReferenceId} to its
126
+ * {@link ChunkSummaryProperties}.
127
+ * Used by {@link ForestIncrementalSummaryBuilder.computeHandlePathInLatestSummary} to traverse
128
+ * the parent chain when generating handle paths.
129
+ */
130
+ readonly latestSummaryRefIdMap: Map<ChunkReferenceId, ChunkSummaryProperties>;
112
131
  }
113
132
 
114
133
  /**
@@ -177,6 +196,16 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
177
196
  /**
178
197
  * For a given summary sequence number, keeps track of a chunk's properties that will be used to generate
179
198
  * a summary handle for the chunk if it does not change between summaries.
199
+ *
200
+ * @remarks
201
+ * `chunk` (the TreeChunk object) is used as the map key by object identity.
202
+ * This assumes each chunk appears at exactly one position in the forest — an invariant that holds because every
203
+ * node in a tree has a single parent.
204
+ * If the forest ever introduced structural sharing (two positions backed by the same TreeChunk object),
205
+ * a second call here would silently overwrite the first entry, causing the first position's handle to point
206
+ * to the second position's parent in subsequent summaries. In theory, this should be fine from summary perspective
207
+ * because the chunk contents are the same. But, it could lead to confusing handle paths in the summary tree and
208
+ * may lead to other unexpected behavior. Adequate tests should be added if structural sharing is introduced.
180
209
  */
181
210
  private readonly chunkTrackingPropertiesMap: NestedMap<
182
211
  number,
@@ -249,12 +278,14 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
249
278
  // the contents of incremental chunks in any sub-trees.
250
279
  const downloadChunkContentsInTree = async (
251
280
  snapshotTree: ISnapshotTree,
252
- parentTreeKey: string,
281
+ parentPathSegments: string[],
282
+ parentReferenceId: ChunkReferenceId | undefined,
253
283
  ): Promise<void> => {
254
284
  // All trees in the snapshot tree are for incremental chunks. The key is the chunk's reference ID
255
285
  // and the value is the snapshot tree for the chunk.
256
286
  for (const [chunkReferenceId, chunkSnapshotTree] of Object.entries(snapshotTree.trees)) {
257
- const chunkSubTreePath = `${parentTreeKey}${chunkReferenceId}`;
287
+ const chunkSubTreeSegments = [...parentPathSegments, chunkReferenceId];
288
+ const chunkSubTreePath = chunkSubTreeSegments.join("/");
258
289
  const chunkContentsPath = `${chunkSubTreePath}/${summaryContentBlobKey}`;
259
290
  if (!(await args.services.contains(chunkContentsPath))) {
260
291
  throw new LoggingError(
@@ -266,7 +297,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
266
297
  )) as EncodedFieldBatchV2; // TODO: this should use a codec to validate the data instead of just type casting.
267
298
  this.loadedChunksMap.set(chunkReferenceId, {
268
299
  encodedContents: chunkContents,
269
- summaryPath: chunkSubTreePath,
300
+ parentReferenceId,
270
301
  });
271
302
 
272
303
  const chunkReferenceIdNumber = Number(chunkReferenceId);
@@ -275,10 +306,15 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
275
306
  );
276
307
 
277
308
  // Recursively download the contents of chunks in this chunk's sub tree.
278
- await downloadChunkContentsInTree(chunkSnapshotTree, `${chunkSubTreePath}/`);
309
+ await downloadChunkContentsInTree(
310
+ chunkSnapshotTree,
311
+ chunkSubTreeSegments,
312
+ brand(chunkReferenceIdNumber),
313
+ );
279
314
  }
280
315
  };
281
- await downloadChunkContentsInTree(forestTree, "");
316
+ // parentReferenceId is undefined for the root of the forest tree.
317
+ await downloadChunkContentsInTree(forestTree, [], undefined /* parentReferenceId */);
282
318
  }
283
319
 
284
320
  /**
@@ -319,6 +355,19 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
319
355
  }
320
356
 
321
357
  this.latestSummarySequenceNumber = incrementalSummaryContext.latestSummarySequenceNumber;
358
+
359
+ // Build a reverse lookup map (referenceId → properties) for the latest summary so that
360
+ // computeHandlePathInLatestSummary can traverse the parent chain without iterating the whole map.
361
+ const latestSummaryRefIdMap: Map<ChunkReferenceId, ChunkSummaryProperties> = new Map();
362
+ const latestTracking = this.chunkTrackingPropertiesMap.get(
363
+ this.latestSummarySequenceNumber,
364
+ );
365
+ if (latestTracking !== undefined) {
366
+ for (const properties of latestTracking.values()) {
367
+ latestSummaryRefIdMap.set(properties.referenceId, properties);
368
+ }
369
+ }
370
+
322
371
  this.trackedSummaryProperties = {
323
372
  summarySequenceNumber: incrementalSummaryContext.summarySequenceNumber,
324
373
  latestSummaryBasePath: incrementalSummaryContext.summaryPath,
@@ -326,10 +375,39 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
326
375
  parentSummaryBuilder: builder,
327
376
  fullTree,
328
377
  stringify,
378
+ latestSummaryRefIdMap,
329
379
  };
330
380
  return ForestIncrementalSummaryBehavior.Incremental;
331
381
  }
332
382
 
383
+ /**
384
+ * Computes a chunk's path in the latest summary by traversing up the parent chain via
385
+ * {@link latestSummaryRefIdMap}.
386
+ *
387
+ * Each {@link ChunkSummaryProperties.parentReferenceId} points to the chunk's parent as it
388
+ * appeared in the summary where the entry was last written. Walking up the chain from the
389
+ * chunk to the root produces the full path that can be used in a summary handle path.
390
+ */
391
+ private computeHandlePathInLatestSummary(chunkProperties: ChunkSummaryProperties): string {
392
+ const { latestSummaryRefIdMap } = this.requireTrackingSummary();
393
+ const pathSegments: string[] = [];
394
+ let current: ChunkSummaryProperties | undefined = chunkProperties;
395
+ while (current !== undefined) {
396
+ pathSegments.push(`${current.referenceId}`);
397
+ if (current.parentReferenceId === undefined) {
398
+ break;
399
+ }
400
+ current = latestSummaryRefIdMap.get(current.parentReferenceId);
401
+ assert(
402
+ current !== undefined,
403
+ 0xcf7 /* Parent chunk not found in latest summary tracking */,
404
+ );
405
+ }
406
+ // Segments are collected leaf-to-root and then reversed. The alternative would be to use unshift
407
+ // instead of push and reverse. However, using push and reverse is O(n) whereas using unshift would be O(n²).
408
+ return pathSegments.reverse().join("/");
409
+ }
410
+
333
411
  /**
334
412
  * {@link IncrementalEncoder.encodeIncrementalField}
335
413
  * @remarks Returns an empty array if the field has no content.
@@ -344,8 +422,6 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
344
422
  const chunkReferenceIds: ChunkReferenceId[] = [];
345
423
  const chunks = this.getChunkAtCursor(cursor);
346
424
  for (const chunk of chunks) {
347
- let chunkProperties: ChunkSummaryProperties;
348
-
349
425
  // Try and get the properties of the chunk from the latest successful summary.
350
426
  // If it exists and the summary is not a full tree, use the properties to generate a summary handle.
351
427
  // If it does not exist, encode the chunk and generate new properties for it.
@@ -354,28 +430,29 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
354
430
  this.latestSummarySequenceNumber,
355
431
  chunk,
356
432
  );
433
+ let chunkReferenceId: ChunkReferenceId;
357
434
  if (previousChunkProperties !== undefined && !trackedSummaryProperties.fullTree) {
358
- chunkProperties = previousChunkProperties;
435
+ chunkReferenceId = previousChunkProperties.referenceId;
436
+ // Compute this chunk's path in the latest summary by traversing the parent chain.
437
+ // Using parentReferenceId traversal (rather than a stored path string) ensures the
438
+ // path is correct even when an ancestor was re-encoded in a prior summary and
439
+ // received a new referenceId — the stored summaryPath would have been stale in
440
+ // that case.
441
+ const handlePath = this.computeHandlePathInLatestSummary(previousChunkProperties);
359
442
  trackedSummaryProperties.parentSummaryBuilder.addHandle(
360
- `${chunkProperties.referenceId}`,
443
+ `${chunkReferenceId}`,
361
444
  SummaryType.Tree,
362
- `${trackedSummaryProperties.latestSummaryBasePath}/${chunkProperties.summaryPath}`,
445
+ `${trackedSummaryProperties.latestSummaryBasePath}/${handlePath}`,
363
446
  );
364
447
  } else {
365
448
  // Generate a new reference ID for the chunk.
366
449
  const newReferenceId: ChunkReferenceId = brand(this.nextReferenceId++);
450
+ chunkReferenceId = newReferenceId;
367
451
 
368
- // Add the reference ID of this chunk to the chunk summary path and use the path as the summary path
369
- // for the chunk in its summary properties.
370
- // This is done before encoding the chunk so that the summary path is updated correctly when encoding
371
- // any incremental chunks that are under this chunk.
452
+ // Add the reference ID of this chunk to the chunk summary path before encoding so
453
+ // that any incremental chunks in the subtree use the correct parent path.
372
454
  trackedSummaryProperties.chunkSummaryPath.push(newReferenceId);
373
455
 
374
- chunkProperties = {
375
- referenceId: newReferenceId,
376
- summaryPath: trackedSummaryProperties.chunkSummaryPath.join("/"),
377
- };
378
-
379
456
  const parentSummaryBuilder = trackedSummaryProperties.parentSummaryBuilder;
380
457
  // Create a new summary builder for this chunk to build its summary tree which will be stored in the
381
458
  // parent's summary tree under its reference ID.
@@ -400,13 +477,21 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
400
477
  trackedSummaryProperties.chunkSummaryPath.pop();
401
478
  }
402
479
 
480
+ // Get the parent reference ID from the current chunk summary path.
481
+ // For the root of the forest tree, the parent reference ID is undefined.
482
+ // For all other chunks, the parent reference ID is the last element in the current chunk summary path.
483
+ const chunkSummaryPathLength = trackedSummaryProperties.chunkSummaryPath.length;
484
+ const parentReferenceId: ChunkReferenceId | undefined =
485
+ chunkSummaryPathLength > 0
486
+ ? trackedSummaryProperties.chunkSummaryPath[chunkSummaryPathLength - 1]
487
+ : undefined;
403
488
  setInNestedMap(
404
489
  this.chunkTrackingPropertiesMap,
405
490
  trackedSummaryProperties.summarySequenceNumber,
406
491
  chunk,
407
- chunkProperties,
492
+ { referenceId: chunkReferenceId, parentReferenceId },
408
493
  );
409
- chunkReferenceIds.push(chunkProperties.referenceId);
494
+ chunkReferenceIds.push(chunkReferenceId);
410
495
  }
411
496
  return chunkReferenceIds;
412
497
  }
@@ -480,9 +565,9 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
480
565
  referenceId: ChunkReferenceId,
481
566
  chunkDecoder: (encoded: EncodedFieldBatchV2) => TreeChunk,
482
567
  ): TreeChunk {
483
- const ChunkLoadProperties = this.loadedChunksMap.get(`${referenceId}`);
484
- assert(ChunkLoadProperties !== undefined, 0xc86 /* Encoded incremental chunk not found */);
485
- const chunk = chunkDecoder(ChunkLoadProperties.encodedContents);
568
+ const chunkLoadProperties = this.loadedChunksMap.get(`${referenceId}`);
569
+ assert(chunkLoadProperties !== undefined, 0xc86 /* Encoded incremental chunk not found */);
570
+ const chunk = chunkDecoder(chunkLoadProperties.encodedContents);
486
571
 
487
572
  // Account for the reference about to be added in `chunkTrackingPropertiesMap`
488
573
  // to ensure that no other users of this chunk think they have unique ownership.
@@ -493,7 +578,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
493
578
  // when a new client starts to summarize.
494
579
  setInNestedMap(this.chunkTrackingPropertiesMap, this.initialSequenceNumber, chunk, {
495
580
  referenceId,
496
- summaryPath: ChunkLoadProperties.summaryPath,
581
+ parentReferenceId: chunkLoadProperties.parentReferenceId,
497
582
  });
498
583
  return chunk;
499
584
  }
@@ -51,6 +51,7 @@ export type KeyFinder<TKey> = (tree: ITreeSubscriptionCursor) => TKey;
51
51
  * calling {@link keys} will not include any keys that are stored in the index but only map to detached nodes.
52
52
  */
53
53
  export class AnchorTreeIndex<TKey, TValue> implements TreeIndex<TKey, TValue> {
54
+ public readonly [Symbol.toStringTag] = "AnchorTreeIndex";
54
55
  public disposed = false;
55
56
  /**
56
57
  * Caches {@link KeyFinder}s for each schema definition. If a schema maps to null, it does not
@@ -3,10 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import type { FluidReadonlyMap } from "@fluidframework/core-interfaces/internal";
7
+
6
8
  /**
7
9
  * an array of nodes that is guaranteed to have at least one element
8
10
  *
9
- * @alpha
11
+ * @beta
10
12
  */
11
13
  export type TreeIndexNodes<TNode> = readonly [first: TNode, ...rest: TNode[]];
12
14
 
@@ -23,9 +25,9 @@ export type TreeIndexNodes<TNode> = readonly [first: TNode, ...rest: TNode[]];
23
25
  * Since currently partially loading a tree is not supported, there is no need for this.
24
26
  * At some point the low level shared tree index type for persisted indexes could be leveraged to provide user facing extensible sets of persisted indexes.
25
27
  * @sealed
26
- * @alpha
28
+ * @beta
27
29
  */
28
- export interface TreeIndex<TKey, TValue> extends ReadonlyMap<TKey, TValue> {
30
+ export interface TreeIndex<TKey, TValue> extends FluidReadonlyMap<TKey, TValue> {
29
31
  /**
30
32
  * Disposes the index such that it can no longer be used and receives no updates for changes in the tree.
31
33
  * @remarks
package/src/index.ts CHANGED
@@ -111,6 +111,7 @@ export {
111
111
  type TreeChangeEvents,
112
112
  type NodeFromSchema,
113
113
  type TreeMapNode,
114
+ type TreeMapNodeAlpha,
114
115
  type InsertableTreeNodeFromImplicitAllowedTypes,
115
116
  type TreeLeafValue,
116
117
  FieldKind,
@@ -136,10 +137,13 @@ export {
136
137
  type ArrayNodeInsertOp,
137
138
  type ArrayNodeRemoveOp,
138
139
  type ArrayNodeRetainOp,
140
+ type ArrayNodeTreeChangedDeltaOp,
141
+ type ArrayNodeTreeChangedRetainOp,
139
142
  type NodeChangedData,
140
143
  type NodeChangedDataAlpha,
141
144
  type NodeChangedDataDelta,
142
145
  type NodeChangedDataProperties,
146
+ type NodeChangedDataTreeDelta,
143
147
  type SchemaUpgrade,
144
148
  contentSchemaSymbol,
145
149
  // Types not really intended for public use, but used in links.
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/tree";
9
- export const pkgVersion = "2.92.0";
9
+ export const pkgVersion = "2.100.0";
@@ -6,6 +6,12 @@
6
6
  import type { IFluidHandle } from "@fluidframework/core-interfaces";
7
7
 
8
8
  import {
9
+ // #region Unused imports to make d.ts cleaner
10
+ /* eslint-disable unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars */
11
+ NodeKind,
12
+ System_Unsafe,
13
+ /* eslint-enable unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars */
14
+ // #endregion
9
15
  SchemaFactory,
10
16
  SchemaFactoryBeta,
11
17
  type FixRecursiveArraySchema,
@@ -240,8 +240,12 @@ export interface TreeAlpha {
240
240
  * @returns A callback function which will deregister the event.
241
241
  * This callback should be called only once.
242
242
  * @remarks
243
- * Provides a richer `nodeChanged` event than {@link (TreeBeta:interface).on} for array nodes the
244
- * event data includes a {@link NodeChangedDataDelta.delta | delta} payload.
243
+ * Provides richer events than {@link (TreeBeta:interface).on} for array nodes:
244
+ * - `nodeChanged` includes a {@link NodeChangedDataDelta.delta | delta} payload for direct
245
+ * changes (insert, remove, move).
246
+ * - `treeChanged` also includes a {@link NodeChangedDataDelta.delta | delta} payload and fires
247
+ * for both shallow changes and deep changes (e.g. a property of an element changed without
248
+ * any direct array change).
245
249
  */
246
250
  on<K extends keyof TreeChangeEventsAlpha<TNode>, TNode extends TreeNode>(
247
251
  node: TNode,
@@ -363,7 +363,12 @@ function* getFieldDiscrepancies(
363
363
  fail(0xbef /* A conversion from a FieldKind to a FlexFieldKind should exist */);
364
364
 
365
365
  // This checks if the field kind in the view schema is not compatible with the stored schema.
366
- if (viewKind.identifier !== stored.kind) {
366
+ // A staged optional field (optional in the view) is compatible with a required stored field
367
+ // during the rollout period — suppress the kind discrepancy in that case.
368
+ if (
369
+ viewKind.identifier !== stored.kind &&
370
+ !(view.isStagedOptional !== false && stored.kind === FieldKinds.required.identifier)
371
+ ) {
367
372
  yield {
368
373
  identifier,
369
374
  fieldKey,
@@ -17,7 +17,7 @@ import type { TreeView } from "./tree.js";
17
17
  /**
18
18
  * An index that returns tree nodes given their associated identifiers.
19
19
  *
20
- * @alpha
20
+ * @beta
21
21
  */
22
22
  export type IdentifierIndex = TreeIndex<string, TreeNode>;
23
23
 
@@ -28,7 +28,7 @@ function isStringKey(key: TreeIndexKey): key is string {
28
28
  /**
29
29
  * Creates an {@link IdentifierIndex} for a given {@link TreeView}.
30
30
  *
31
- * @alpha
31
+ * @beta
32
32
  */
33
33
  export function createIdentifierIndex<TSchema extends ImplicitFieldSchema>(
34
34
  view: TreeView<TSchema>,
@@ -66,6 +66,7 @@ export {
66
66
  createCustomizedFluidFrameworkScopedFactory,
67
67
  } from "./schemaCreationUtilities.js";
68
68
  export {
69
+ deltaMarksToArrayOps,
69
70
  getIdentifierFromNode,
70
71
  getPropertyKeyFromStoredKey,
71
72
  getStoredKey,
@@ -158,9 +159,12 @@ export {
158
159
  type ArrayNodeInsertOp,
159
160
  type ArrayNodeRemoveOp,
160
161
  type ArrayNodeRetainOp,
162
+ type ArrayNodeTreeChangedDeltaOp,
163
+ type ArrayNodeTreeChangedRetainOp,
161
164
  type NodeChangedDataAlpha,
162
165
  type NodeChangedDataDelta,
163
166
  type NodeChangedDataProperties,
167
+ type NodeChangedDataTreeDelta,
164
168
  type TreeChangeEventsAlpha,
165
169
  } from "./treeAlpha.js";
166
170
  export { createTreeIndex, type TreeIndexKey } from "./simpleTreeIndex.js";
@@ -11,6 +11,7 @@ import {
11
11
  type WithType,
12
12
  normalizeAllowedTypes,
13
13
  isTreeNode,
14
+ createSchemaUpgrade,
14
15
  } from "../core/index.js";
15
16
  // These imports prevent a large number of type references in the API reports from showing up as *_2.
16
17
  /* eslint-disable unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars, import-x/no-duplicates */
@@ -18,7 +19,7 @@ import {
18
19
  type FieldProps,
19
20
  type FieldSchemaAlpha,
20
21
  type FieldPropsAlpha,
21
- type FieldKind,
22
+ FieldKind,
22
23
  type ImplicitFieldSchema,
23
24
  type InsertableTreeFieldFromImplicitField,
24
25
  type FieldSchema,
@@ -143,6 +144,64 @@ export interface SchemaStaticsAlpha {
143
144
  TCustomMetadata,
144
145
  FieldPropsAlpha<TCustomMetadata> & { defaultProvider: DefaultProvider }
145
146
  >;
147
+ /**
148
+ * Creates a field schema that is Optional in the view but behaves as Required in the stored schema
149
+ * during the rollout period of an optional-field migration.
150
+ *
151
+ * @remarks
152
+ * Use this to incrementally migrate a required field to optional without a coordinated deployment.
153
+ * The migration path is:
154
+ *
155
+ * 1. Start with `sf.required(T)` — all clients require the field.
156
+ * 2. Deploy `sf.stagedOptional(T)` — new clients can read documents where the field is present or absent, but the stored schema stays Required (so old clients are unaffected). Setting the field to `undefined` is rejected because the stored schema still declares the field as required.
157
+ * 3. Deploy `sf.optional(T)` once all clients support the staged optional field — the stored schema becomes Optional and the field can be cleared.
158
+ *
159
+ * Analogous to {@link SchemaStaticsBeta.staged} for allowed types, but for field optionality.
160
+ *
161
+ * @param t - The types allowed under the field.
162
+ * @param props - Optional properties to associate with the field.
163
+ *
164
+ * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.
165
+ * See {@link FieldSchemaMetadata.custom}.
166
+ */
167
+ readonly stagedOptional: <
168
+ const T extends ImplicitAllowedTypes,
169
+ const TCustomMetadata = unknown,
170
+ >(
171
+ t: T,
172
+ props?: Omit<
173
+ FieldPropsAlpha<TCustomMetadata>,
174
+ "defaultProvider" | "stagedOptionalUpgrade"
175
+ >,
176
+ ) => FieldSchemaAlpha<
177
+ FieldKind.Optional,
178
+ T,
179
+ TCustomMetadata,
180
+ FieldPropsAlpha<TCustomMetadata>
181
+ >;
182
+ /**
183
+ * {@link SchemaStaticsAlpha.stagedOptional} except tweaked to work better for recursive types.
184
+ * Use with {@link ValidateRecursiveSchema} for improved type safety.
185
+ * @remarks
186
+ * This version of {@link SchemaStaticsAlpha.stagedOptional} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.
187
+ * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.
188
+ */
189
+ readonly stagedOptionalRecursive: <
190
+ const T extends System_Unsafe.ImplicitAllowedTypesUnsafe,
191
+ const TCustomMetadata = unknown,
192
+ >(
193
+ t: T,
194
+ props?: Omit<
195
+ FieldPropsAlpha<TCustomMetadata>,
196
+ "defaultProvider" | "stagedOptionalUpgrade"
197
+ >,
198
+ ) => FieldSchemaAlphaUnsafe<
199
+ FieldKind.Optional,
200
+ T,
201
+ TCustomMetadata,
202
+ FieldPropsAlpha<TCustomMetadata>
203
+ >;
204
+
146
205
  /**
147
206
  * {@link SchemaStaticsAlpha.withDefault} except tweaked to work better for recursive types.
148
207
  * Use with {@link ValidateRecursiveSchema} for improved type safety.
@@ -225,10 +284,27 @@ const withDefault = <
225
284
  );
226
285
  };
227
286
 
287
+ const stagedOptional = <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(
288
+ t: T,
289
+ props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider" | "stagedOptionalUpgrade">,
290
+ ): FieldSchemaAlpha<
291
+ FieldKind.Optional,
292
+ T,
293
+ TCustomMetadata,
294
+ FieldPropsAlpha<TCustomMetadata>
295
+ > => {
296
+ return createFieldSchema(FieldKind.Optional, t, {
297
+ defaultProvider: getDefaultProvider(() => []),
298
+ ...props,
299
+ stagedOptionalUpgrade: createSchemaUpgrade(),
300
+ });
301
+ };
302
+
228
303
  const schemaStaticsAlpha: SchemaStaticsAlpha = {
229
304
  withDefault,
230
-
231
305
  withDefaultRecursive: withDefault as SchemaStaticsAlpha["withDefaultRecursive"],
306
+ stagedOptional,
307
+ stagedOptionalRecursive: stagedOptional as SchemaStaticsAlpha["stagedOptionalRecursive"],
232
308
  };
233
309
 
234
310
  /**
@@ -448,7 +524,27 @@ export class SchemaFactoryAlpha<
448
524
  public static readonly withDefaultRecursive = schemaStaticsAlpha.withDefaultRecursive;
449
525
 
450
526
  /**
451
- * Define a {@link TreeNodeSchema} for a {@link TreeMapNode}.
527
+ * {@inheritdoc SchemaStaticsAlpha.stagedOptional}
528
+ */
529
+ public readonly stagedOptional = schemaStaticsAlpha.stagedOptional;
530
+
531
+ /**
532
+ * {@inheritdoc SchemaStaticsAlpha.stagedOptional}
533
+ */
534
+ public static readonly stagedOptional = schemaStaticsAlpha.stagedOptional;
535
+
536
+ /**
537
+ * {@inheritdoc SchemaStaticsAlpha.stagedOptionalRecursive}
538
+ */
539
+ public readonly stagedOptionalRecursive = schemaStaticsAlpha.stagedOptionalRecursive;
540
+
541
+ /**
542
+ * {@inheritdoc SchemaStaticsAlpha.stagedOptionalRecursive}
543
+ */
544
+ public static readonly stagedOptionalRecursive = schemaStaticsAlpha.stagedOptionalRecursive;
545
+
546
+ /**
547
+ * Define a {@link TreeNodeSchema} for a {@link TreeMapNodeAlpha}.
452
548
  *
453
549
  * @param name - Unique identifier for this schema within this factory's scope.
454
550
  * @param allowedTypes - The types that may appear as values in the map.
@@ -39,7 +39,7 @@ import { treeNodeApi } from "./treeNodeApi.js";
39
39
  * @remarks
40
40
  * This supports values which have value semantics and are compared by value, just like {@link TreeLeafValue}.
41
41
  * This allows using any tree value as a key (for example in an index tracking where those values occur in the tree).
42
- * @alpha
42
+ * @beta
43
43
  */
44
44
  export type TreeIndexKey = TreeLeafValue;
45
45
 
@@ -52,7 +52,7 @@ export type TreeIndexKey = TreeLeafValue;
52
52
  * @param getValue - given at least one {@link TreeNode}, returns an associated value
53
53
  * @param isKeyValid - function for verifying the validity of the key retrieved based on the information given by the indexer
54
54
  *
55
- * @alpha
55
+ * @beta
56
56
  */
57
57
  export function createTreeIndex<
58
58
  TFieldSchema extends ImplicitFieldSchema,
@@ -75,7 +75,7 @@ export function createTreeIndex<
75
75
  * @param isKeyValid - function for verifying the validity of the key retrieved based on the information given by the indexer
76
76
  * @param indexableSchema - a list of all the schema types that can be indexed
77
77
  *
78
- * @alpha
78
+ * @beta
79
79
  */
80
80
  export function createTreeIndex<
81
81
  TFieldSchema extends ImplicitFieldSchema,
@@ -99,7 +99,7 @@ export function createTreeIndex<
99
99
  * @param getValue - given at least one {@link TreeNode}, returns an associated value
100
100
  * @param isKeyValid - function for verifying the validity of the key retrieved based on the information given by the indexer
101
101
  *
102
- * @alpha
102
+ * @beta
103
103
  */
104
104
  export function createTreeIndex<
105
105
  TFieldSchema extends ImplicitFieldSchema,
@@ -122,7 +122,7 @@ export function createTreeIndex<
122
122
  * @param isKeyValid - function for verifying the validity of the key retrieved based on the information given by the indexer
123
123
  * @param indexableSchema - a list of all the schema types that can be indexed
124
124
  *
125
- * @alpha
125
+ * @beta
126
126
  */
127
127
  export function createTreeIndex<
128
128
  TFieldSchema extends ImplicitFieldSchema,
@@ -140,7 +140,7 @@ export function createTreeIndex<
140
140
  /**
141
141
  * Creates a {@link TreeIndex} with a specified indexer.
142
142
  *
143
- * @alpha
143
+ * @beta
144
144
  */
145
145
  export function createTreeIndex<
146
146
  TFieldSchema extends ImplicitFieldSchema,
@@ -53,7 +53,10 @@ export function extractPersistedSchema(
53
53
  minVersionForCollab: MinimumVersionForCollab,
54
54
  includeStaged: (upgrade: SchemaUpgrade) => boolean,
55
55
  ): JsonCompatible {
56
- const stored = toStoredSchema(schema, { includeStaged });
56
+ const stored = toStoredSchema(schema, {
57
+ includeStaged,
58
+ includeStagedOptional: includeStaged,
59
+ });
57
60
  const codec = schemaCodecBuilder.build({
58
61
  minVersionForCollab,
59
62
  jsonValidator: FormatValidatorNoOp,