@fluidframework/tree 2.93.0 → 2.101.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 (273) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/INCREMENTAL_SUMMARY.md +89 -0
  3. package/README.md +6 -0
  4. package/api-report/tree.alpha.api.md +6 -1
  5. package/api-report/tree.beta.api.md +3 -1
  6. package/api-report/tree.legacy.beta.api.md +3 -1
  7. package/dist/core/change-family/changeFamily.d.ts +23 -0
  8. package/dist/core/change-family/changeFamily.d.ts.map +1 -1
  9. package/dist/core/change-family/changeFamily.js.map +1 -1
  10. package/dist/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
  11. package/dist/core/tree/detachedFieldIndexCodecV1.js +2 -0
  12. package/dist/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
  13. package/dist/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
  14. package/dist/core/tree/detachedFieldIndexCodecV2.js +2 -0
  15. package/dist/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
  16. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +25 -1
  17. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  18. package/dist/feature-libraries/chunked-forest/basicChunk.js +71 -18
  19. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  20. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -4
  21. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  22. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +31 -4
  23. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  24. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +27 -0
  25. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  26. package/dist/feature-libraries/chunked-forest/codec/codecs.js +5 -2
  27. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  28. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +10 -2
  29. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  30. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +7 -2
  31. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  32. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +1 -2
  33. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
  34. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +0 -1
  35. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts +1 -1
  37. package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/codec/format/index.js +2 -1
  39. package/dist/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
  40. package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts +10 -2
  41. package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
  42. package/dist/feature-libraries/chunked-forest/codec/format/versions.js +15 -1
  43. package/dist/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts.map +1 -1
  45. package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.js +9 -1
  46. package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.js.map +1 -1
  47. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +3 -3
  48. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  49. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +8 -8
  50. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  51. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts +6 -1
  52. package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  53. package/dist/feature-libraries/chunked-forest/uniformChunk.js +25 -1
  54. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  55. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +19 -0
  56. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  57. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +76 -22
  58. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  59. package/dist/feature-libraries/modular-schema/genericFieldKindFormat.d.ts +2 -14
  60. package/dist/feature-libraries/modular-schema/genericFieldKindFormat.d.ts.map +1 -1
  61. package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js +1 -17
  62. package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
  63. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
  64. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +4 -0
  65. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
  66. package/dist/packageVersion.d.ts +1 -1
  67. package/dist/packageVersion.d.ts.map +1 -1
  68. package/dist/packageVersion.js +1 -1
  69. package/dist/packageVersion.js.map +1 -1
  70. package/dist/shared-tree/independentView.d.ts.map +1 -1
  71. package/dist/shared-tree/independentView.js +2 -0
  72. package/dist/shared-tree/independentView.js.map +1 -1
  73. package/dist/shared-tree/sharedTree.d.ts +35 -1
  74. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  75. package/dist/shared-tree/sharedTree.js +6 -0
  76. package/dist/shared-tree/sharedTree.js.map +1 -1
  77. package/dist/shared-tree/sharedTreeChangeCodecs.js +1 -0
  78. package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  79. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  80. package/dist/shared-tree/treeAlpha.js +2 -0
  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/shared-tree/treeCheckout.js +2 -0
  85. package/dist/shared-tree/treeCheckout.js.map +1 -1
  86. package/dist/shared-tree-core/editManagerCodecs.d.ts +3 -0
  87. package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  88. package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
  89. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +14 -0
  90. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  91. package/dist/shared-tree-core/editManagerCodecsCommons.js +14 -0
  92. package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  93. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts +3 -0
  94. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  95. package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  96. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +3 -0
  97. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  98. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  99. package/dist/shared-tree-core/editManagerSummarizer.d.ts +9 -1
  100. package/dist/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
  101. package/dist/shared-tree-core/editManagerSummarizer.js +20 -5
  102. package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
  103. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  104. package/dist/shared-tree-core/messageCodecV1ToV4.js +4 -0
  105. package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  106. package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  107. package/dist/shared-tree-core/messageCodecVSharedBranches.js +4 -0
  108. package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  109. package/dist/shared-tree-core/sharedTreeCore.d.ts +4 -0
  110. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  111. package/dist/shared-tree-core/sharedTreeCore.js +1 -1
  112. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  113. package/dist/simple-tree/api/schemaFactory.d.ts +3 -3
  114. package/dist/simple-tree/api/schemaFactory.js +3 -3
  115. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  116. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
  117. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  118. package/dist/simple-tree/api/schemaFactoryAlpha.js +9 -0
  119. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  120. package/dist/tableSchema.d.ts.map +1 -1
  121. package/dist/tableSchema.js +102 -20
  122. package/dist/tableSchema.js.map +1 -1
  123. package/docs/user-facing/isolated-declarations.md +147 -0
  124. package/lib/core/change-family/changeFamily.d.ts +23 -0
  125. package/lib/core/change-family/changeFamily.d.ts.map +1 -1
  126. package/lib/core/change-family/changeFamily.js.map +1 -1
  127. package/lib/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
  128. package/lib/core/tree/detachedFieldIndexCodecV1.js +2 -0
  129. package/lib/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
  130. package/lib/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
  131. package/lib/core/tree/detachedFieldIndexCodecV2.js +2 -0
  132. package/lib/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
  133. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +25 -1
  134. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  135. package/lib/feature-libraries/chunked-forest/basicChunk.js +72 -19
  136. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  137. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -4
  138. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  139. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +32 -5
  140. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  141. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +27 -0
  142. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  143. package/lib/feature-libraries/chunked-forest/codec/codecs.js +6 -3
  144. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  145. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +10 -2
  146. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  147. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +8 -3
  148. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  149. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +1 -2
  150. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
  151. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js +0 -1
  152. package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
  153. package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts +1 -1
  154. package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
  155. package/lib/feature-libraries/chunked-forest/codec/format/index.js +1 -1
  156. package/lib/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
  157. package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts +10 -2
  158. package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
  159. package/lib/feature-libraries/chunked-forest/codec/format/versions.js +13 -0
  160. package/lib/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
  161. package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts.map +1 -1
  162. package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.js +9 -1
  163. package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.js.map +1 -1
  164. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +3 -3
  165. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  166. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +8 -8
  167. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  168. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts +6 -1
  169. package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
  170. package/lib/feature-libraries/chunked-forest/uniformChunk.js +26 -2
  171. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  172. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +19 -0
  173. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  174. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +76 -22
  175. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  176. package/lib/feature-libraries/modular-schema/genericFieldKindFormat.d.ts +2 -14
  177. package/lib/feature-libraries/modular-schema/genericFieldKindFormat.d.ts.map +1 -1
  178. package/lib/feature-libraries/modular-schema/genericFieldKindFormat.js +1 -17
  179. package/lib/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
  180. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
  181. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +4 -0
  182. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
  183. package/lib/packageVersion.d.ts +1 -1
  184. package/lib/packageVersion.d.ts.map +1 -1
  185. package/lib/packageVersion.js +1 -1
  186. package/lib/packageVersion.js.map +1 -1
  187. package/lib/shared-tree/independentView.d.ts.map +1 -1
  188. package/lib/shared-tree/independentView.js +2 -0
  189. package/lib/shared-tree/independentView.js.map +1 -1
  190. package/lib/shared-tree/sharedTree.d.ts +35 -1
  191. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  192. package/lib/shared-tree/sharedTree.js +6 -0
  193. package/lib/shared-tree/sharedTree.js.map +1 -1
  194. package/lib/shared-tree/sharedTreeChangeCodecs.js +1 -0
  195. package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  196. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  197. package/lib/shared-tree/treeAlpha.js +2 -0
  198. package/lib/shared-tree/treeAlpha.js.map +1 -1
  199. package/lib/shared-tree/treeCheckout.d.ts +1 -1
  200. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  201. package/lib/shared-tree/treeCheckout.js +2 -0
  202. package/lib/shared-tree/treeCheckout.js.map +1 -1
  203. package/lib/shared-tree-core/editManagerCodecs.d.ts +3 -0
  204. package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  205. package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
  206. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +14 -0
  207. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  208. package/lib/shared-tree-core/editManagerCodecsCommons.js +14 -0
  209. package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  210. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts +3 -0
  211. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  212. package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  213. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +3 -0
  214. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  215. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  216. package/lib/shared-tree-core/editManagerSummarizer.d.ts +9 -1
  217. package/lib/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
  218. package/lib/shared-tree-core/editManagerSummarizer.js +20 -5
  219. package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
  220. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  221. package/lib/shared-tree-core/messageCodecV1ToV4.js +4 -0
  222. package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  223. package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  224. package/lib/shared-tree-core/messageCodecVSharedBranches.js +4 -0
  225. package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  226. package/lib/shared-tree-core/sharedTreeCore.d.ts +4 -0
  227. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  228. package/lib/shared-tree-core/sharedTreeCore.js +1 -1
  229. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  230. package/lib/simple-tree/api/schemaFactory.d.ts +3 -3
  231. package/lib/simple-tree/api/schemaFactory.js +3 -3
  232. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  233. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
  234. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  235. package/lib/simple-tree/api/schemaFactoryAlpha.js +9 -0
  236. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  237. package/lib/tableSchema.d.ts.map +1 -1
  238. package/lib/tableSchema.js +103 -21
  239. package/lib/tableSchema.js.map +1 -1
  240. package/package.json +24 -24
  241. package/src/core/change-family/changeFamily.ts +25 -0
  242. package/src/core/tree/detachedFieldIndexCodecV1.ts +2 -0
  243. package/src/core/tree/detachedFieldIndexCodecV2.ts +2 -0
  244. package/src/feature-libraries/chunked-forest/basicChunk.ts +76 -20
  245. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +61 -12
  246. package/src/feature-libraries/chunked-forest/codec/codecs.ts +34 -1
  247. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +9 -3
  248. package/src/feature-libraries/chunked-forest/codec/format/formatGeneric.ts +0 -1
  249. package/src/feature-libraries/chunked-forest/codec/format/index.ts +1 -0
  250. package/src/feature-libraries/chunked-forest/codec/format/versions.ts +15 -0
  251. package/src/feature-libraries/chunked-forest/codec/nodeEncoder.ts +9 -1
  252. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +9 -1
  253. package/src/feature-libraries/chunked-forest/uniformChunk.ts +32 -2
  254. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +116 -31
  255. package/src/feature-libraries/modular-schema/genericFieldKindFormat.ts +3 -21
  256. package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +4 -0
  257. package/src/packageVersion.ts +1 -1
  258. package/src/shared-tree/independentView.ts +2 -0
  259. package/src/shared-tree/sharedTree.ts +41 -1
  260. package/src/shared-tree/sharedTreeChangeCodecs.ts +1 -0
  261. package/src/shared-tree/treeAlpha.ts +2 -0
  262. package/src/shared-tree/treeCheckout.ts +2 -0
  263. package/src/shared-tree-core/editManagerCodecs.ts +3 -0
  264. package/src/shared-tree-core/editManagerCodecsCommons.ts +29 -0
  265. package/src/shared-tree-core/editManagerCodecsV1toV4.ts +3 -0
  266. package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +3 -0
  267. package/src/shared-tree-core/editManagerSummarizer.ts +17 -5
  268. package/src/shared-tree-core/messageCodecV1ToV4.ts +4 -0
  269. package/src/shared-tree-core/messageCodecVSharedBranches.ts +5 -1
  270. package/src/shared-tree-core/sharedTreeCore.ts +8 -1
  271. package/src/simple-tree/api/schemaFactory.ts +3 -3
  272. package/src/simple-tree/api/schemaFactoryAlpha.ts +34 -3
  273. package/src/tableSchema.ts +134 -35
package/CHANGELOG.md CHANGED
@@ -1,5 +1,79 @@
1
1
  # @fluidframework/tree
2
2
 
3
+ ## 2.101.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add SharedTreeOptionsBeta.healUnresolvableIdentifiersOnDecode to recover documents with corrupted identifiers ([#27281](https://github.com/microsoft/FluidFramework/pull/27281)) [d9205ddcd6a](https://github.com/microsoft/FluidFramework/commit/d9205ddcd6a9f0ec11d5422b38e30a6a91a9258c)
8
+
9
+ A SharedTree bug can result in corrupted documents due to their attach summary compressing identifier-field values in a way that cannot be uncompressed.
10
+ This bug manifested as remote clients processing the op throwing an error with the message "Unknown op space ID.".
11
+
12
+ This change adds an option (`healUnresolvableIdentifiersOnDecode`) to `configuredSharedTreeBetaLegacy` which will allow documents affected by this bug to load again when enabled.
13
+ Enabling this option carries some risk, see documentation on the interface itself for more details.
14
+
15
+ #### Who is affected
16
+
17
+ Only SharedTrees attached to a container that was already attached can be impacted.
18
+ Furthermore, this bug only occurs when the attached tree contains [`identifier`](https://fluidframework.com/docs/api/tree/schemafactory-class#identifier-property) fields which contain implicitly generated default values.
19
+
20
+ - Fix a SharedTree document corruption bug ([#27292](https://github.com/microsoft/FluidFramework/pull/27292)) [6f4cdcb7a0a](https://github.com/microsoft/FluidFramework/commit/6f4cdcb7a0a76ba215a361c7b3a12943750fe286)
21
+
22
+ A SharedTree bug which could corrupt documents when attaching them to containers has been fixed.
23
+ See `healUnresolvableIdentifiersOnDecode` on `configuredSharedTreeBetaLegacy` for a potential mitigation path for documents that were already corrupted by this bug.
24
+
25
+ #### Who is affected
26
+
27
+ Only SharedTrees attached to a container that was already attached can be impacted.
28
+ Furthermore, this bug only occurs when the attached tree contains [`identifier`](https://fluidframework.com/docs/api/tree/schemafactory-class#identifier-property) fields which contain implicitly generated default values.
29
+
30
+ ## 2.100.0
31
+
32
+ ### Minor Changes
33
+
34
+ - Node 22 is now the minimum supported Node.js version ([#27116](https://github.com/microsoft/FluidFramework/pull/27116)) [e8214d29663](https://github.com/microsoft/FluidFramework/commit/e8214d29663f5ee98d737daed82506a25d8de8d0)
35
+
36
+ All Fluid Framework client packages now require Node.js 22 or later. This aligns with the standing Node upgrade policy as Node 20 reaches end-of-life on April 30, 2026.
37
+
38
+ - Add SchemaFactoryAlpha.stagedOptionalRecursive for recursive staged-optional fields ([#27042](https://github.com/microsoft/FluidFramework/pull/27042)) [a6e084e2b66](https://github.com/microsoft/FluidFramework/commit/a6e084e2b66a1dd020aecafc74d163806481e55c)
39
+
40
+ `SchemaFactoryAlpha.stagedOptionalRecursive(T)` is the recursive-type variant of `stagedOptional` (released in [2.93.0](https://github.com/microsoft/FluidFramework/pull/26918)). Use it for schemas whose types are recursive - the relaxed type constraints work around TypeScript's limitations with recursive schema definitions. Pair it with `ValidateRecursiveSchema` for improved type safety.
41
+
42
+ Example:
43
+
44
+ ```typescript
45
+ const sf = new SchemaFactoryAlpha("my-app");
46
+ class TreeNode extends sf.objectRecursiveAlpha("TreeNode", {
47
+ value: sf.number,
48
+ child: sf.stagedOptionalRecursive([() => TreeNode]),
49
+ }) {}
50
+ type _check = ValidateRecursiveSchema<typeof TreeNode>;
51
+ ```
52
+
53
+ See `stagedOptional` for the migration pattern (required to stagedOptional to optional).
54
+
55
+ - Fixed incremental summary bug in SharedTree that may cause repeated summary failures eventually leading to document corruption ([#26990](https://github.com/microsoft/FluidFramework/pull/26990)) [1514c310319](https://github.com/microsoft/FluidFramework/commit/1514c310319074fca0c45449527a336d48801b84)
56
+
57
+ Incremental summary for SharedTree is off by default. This bug only affects applications that have explicitly enabled incremental summarization.
58
+
59
+ **Affected configurations**
60
+
61
+ A session could be affected if all the following were true:
62
+ - Incremental summarization was enabled (opt-in feature, off by default).
63
+ - The SharedTree schema had incremental fields nested at least 2 levels deep. For example, a map field marked with `incrementalSummaryHint` that contains objects which themselves have a map field also marked with `incrementalSummaryHint`.
64
+ - The document was summarized multiple times, with the outer incremental field changing in at least one summary while the inner incremental field remained unchanged.
65
+
66
+ **Symptoms**
67
+
68
+ Summaries would fail. Depending on the storage service, the error may appear as:
69
+ - `TypeError: Cannot read properties of undefined (reading 'trees')` (for example, when using SharePoint storage)
70
+
71
+ Repeated summary failures can cause a session to accumulate ops without a summary. Once the limit of ops without a summary is reached (~10k), further ops will be rejected, making the document read-only for that session.
72
+
73
+ **Mitigation and recovery**
74
+ - If a session is already affected, turning off incremental summarization will allow summaries to succeed again.
75
+ - Upgrade to this version to prevent further summary failures.
76
+
3
77
  ## 2.93.0
4
78
 
5
79
  ### Minor Changes
@@ -0,0 +1,89 @@
1
+ # Incremental Summary
2
+
3
+ Incremental summary is an optimization that avoids re-summarizing parts of the tree that don't change between summaries. Types in a schema can opt in to incremental summarization by being marked with `incrementalSummaryHint`. These types are tracked as independent chunks in the summary. During summarization, if their content hasn't changed since the last summary, their previously generated summaries are reused. As a result, their data doesn't need to be re-encoded (saving processing time), and their summary trees don't need to be uploaded again (reducing summary upload size).
4
+
5
+ > **Warning:** This is an alpha API and is actively under development. Interfaces and behavior may change in future releases without notice. Do not rely on it in production.
6
+
7
+ ## Requirements
8
+
9
+ All five of the following must be set for incremental summary to take effect:
10
+
11
+ | Requirement | Value |
12
+ |---|---|
13
+ | Forest type | [`ForestTypeOptimized`](./src/shared-tree/sharedTree.ts) |
14
+ | Compression strategy | [`TreeCompressionStrategy.CompressedIncremental`](./src/feature-libraries/treeCompressionUtils.ts) |
15
+ | [`shouldEncodeIncrementally`](./src/shared-tree/sharedTree.ts) option | result of [`incrementalEncodingPolicyForAllowedTypes(config)`](./src/simple-tree/api/incrementalAllowedTypes.ts) |
16
+ | `minVersionForCollab` | [`FluidClientVersion.v2_74`](./src/codec/codec.ts) or higher |
17
+ | Schema opt-in | Fields marked with [`incrementalSummaryHint`](./src/simple-tree/api/incrementalAllowedTypes.ts) |
18
+
19
+ ## How to Enable
20
+
21
+ ### 1. Mark fields in your schema
22
+
23
+ Use `sf.types(...)` with `incrementalSummaryHint` in the `custom` metadata to opt a field in.
24
+
25
+ ```typescript
26
+ import { SchemaFactoryAlpha, incrementalSummaryHint } from "@fluidframework/tree/alpha";
27
+
28
+ const sf = new SchemaFactoryAlpha("my-app");
29
+
30
+ class Item extends sf.objectAlpha("Item", {
31
+ id: sf.number,
32
+ // This field will be incrementally summarized.
33
+ payload: sf.types([{ type: sf.string, metadata: {} }], {
34
+ custom: { [incrementalSummaryHint]: true },
35
+ }),
36
+ }) {}
37
+
38
+ class ItemList extends sf.arrayAlpha(
39
+ "ItemList",
40
+ // Each element of this array will be tracked as a separate incremental chunk.
41
+ sf.types([{ type: Item, metadata: {} }], {
42
+ custom: { [incrementalSummaryHint]: true },
43
+ }),
44
+ ) {}
45
+
46
+ class Root extends sf.objectAlpha("Root", {
47
+ items: ItemList,
48
+ }) {}
49
+ ```
50
+
51
+ > **Note:** Incremental summarization is applied to **fields**, not node kinds. Leaf values (string, number, boolean, null) can be incrementally summarized when they are stored in a field that is opted in via `incrementalSummaryHint` (for example, an object field whose allowed type is `string`). Root fields themselves cannot be incrementally summarized, and leaf node kinds do not expose child fields for the policy to apply to.
52
+
53
+ ### 2. Configure the SharedTree
54
+
55
+ Pass all four required options when creating the SharedTree using `configuredSharedTreeAlpha`:
56
+
57
+ ```typescript
58
+ import {
59
+ configuredSharedTreeAlpha,
60
+ ForestTypeOptimized,
61
+ TreeCompressionStrategy,
62
+ TreeViewConfigurationAlpha,
63
+ incrementalEncodingPolicyForAllowedTypes,
64
+ FluidClientVersion,
65
+ } from "@fluidframework/tree/alpha";
66
+
67
+ const config = new TreeViewConfigurationAlpha({ schema: Root });
68
+
69
+ const TreeFactory = configuredSharedTreeAlpha({
70
+ forest: ForestTypeOptimized,
71
+ treeEncodeType: TreeCompressionStrategy.CompressedIncremental,
72
+ shouldEncodeIncrementally: incrementalEncodingPolicyForAllowedTypes(config),
73
+ minVersionForCollab: FluidClientVersion.v2_74,
74
+ });
75
+
76
+ const sharedTree = TreeFactory.create(runtime, "tree");
77
+ ```
78
+
79
+ ## How `incrementalEncodingPolicyForAllowedTypes` Works
80
+
81
+ `incrementalEncodingPolicyForAllowedTypes` takes a `TreeSchema` (typically a `TreeViewConfiguration`) and returns an `IncrementalEncodingPolicy` callback. During summarization, the callback is invoked for each field in the tree with the node identifier and field key. It returns `true` if the field was opted in via `incrementalSummaryHint`, directing the summarizer to encode that field as a separate, reusable chunk.
82
+
83
+ Fields that are _not_ opted in are encoded into the main summary blob as usual.
84
+
85
+ ## Limitations and future work
86
+
87
+ - Root fields cannot be incrementally summarized (the callback always returns `false` for them).
88
+ - If the view schema doesn't recognize a node type (e.g., due to schema mismatch or unknown optional fields), that node falls back to non-incremental encoding.
89
+ - This feature is `@alpha` and the `incrementalSummaryHint` symbol will be replaced by a dedicated metadata property once the APIs stabilize.
package/README.md CHANGED
@@ -193,6 +193,12 @@ class Holder extends schemaFactory.object("Holder", { item: itemTypes }) {}
193
193
  const holder = new Holder({ item: new ItemA({ a: 42 }) });
194
194
  ```
195
195
 
196
+ ### How do I effectively use SharedTree when using TypeScript's `isolatedDeclarations`?
197
+
198
+ SharedTree schema heavily use expression types and class expressions as base classes, both of which `isolatedDeclarations` disallows.
199
+
200
+ See [isolated-declarations.md](docs/user-facing/isolated-declarations.md) for an explanation of the problem and recommended approaches for using SharedTree schema in a project that requires `isolatedDeclarations`.
201
+
196
202
  ## Architecture
197
203
 
198
204
  This section covers the internal structure of the Tree DDS.
@@ -1143,6 +1143,8 @@ export class SchemaFactoryAlpha<out TScope extends string | undefined = string |
1143
1143
  scopedFactoryAlpha<const T extends TName, TNameInner extends number | string = string>(name: T): SchemaFactoryAlpha<ScopedSchemaName<TScope, T>, TNameInner>;
1144
1144
  readonly stagedOptional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1145
1145
  static readonly stagedOptional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1146
+ readonly stagedOptionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1147
+ static readonly stagedOptionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "stagedOptionalUpgrade" | "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1146
1148
  readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1147
1149
  defaultProvider: DefaultProvider;
1148
1150
  }>;
@@ -1201,6 +1203,7 @@ export interface SchemaStatics {
1201
1203
  // @alpha @sealed @system
1202
1204
  export interface SchemaStaticsAlpha {
1203
1205
  readonly stagedOptional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider" | "stagedOptionalUpgrade">) => FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1206
+ readonly stagedOptionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider" | "stagedOptionalUpgrade">) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata, FieldPropsAlpha<TCustomMetadata>>;
1204
1207
  readonly withDefault: <Kind extends FieldKind, Types extends ImplicitAllowedTypes, TCustomMetadata = unknown>(fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>, defaultValue: NodeProvider<InsertableTreeFieldFromImplicitField<FieldSchema<Kind, Types>>>) => FieldSchemaAlpha<Kind, Types, TCustomMetadata, FieldPropsAlpha<TCustomMetadata> & {
1205
1208
  defaultProvider: DefaultProvider;
1206
1209
  }>;
@@ -1244,7 +1247,9 @@ export interface SharedTreeOptions extends SharedTreeOptionsBeta, Partial<CodecW
1244
1247
  }
1245
1248
 
1246
1249
  // @beta @input
1247
- export type SharedTreeOptionsBeta = ForestOptions & Partial<CodecWriteOptionsBeta>;
1250
+ export interface SharedTreeOptionsBeta extends ForestOptions, Partial<CodecWriteOptionsBeta> {
1251
+ readonly healUnresolvableIdentifiersOnDecode?: boolean;
1252
+ }
1248
1253
 
1249
1254
  // @alpha @sealed
1250
1255
  export interface SimpleAllowedTypeAttributes<out Type extends SchemaType = SchemaType> {
@@ -597,7 +597,9 @@ export class SchemaUpgrade {
597
597
  type ScopedSchemaName<TScope extends string | undefined, TName extends number | string> = TScope extends undefined ? `${TName}` : `${TScope}.${TName}`;
598
598
 
599
599
  // @beta @input
600
- export type SharedTreeOptionsBeta = ForestOptions & Partial<CodecWriteOptionsBeta>;
600
+ export interface SharedTreeOptionsBeta extends ForestOptions, Partial<CodecWriteOptionsBeta> {
601
+ readonly healUnresolvableIdentifiersOnDecode?: boolean;
602
+ }
601
603
 
602
604
  // @public @sealed @system
603
605
  export interface SimpleNodeSchemaBase<out TNodeKind extends NodeKind, out TCustomMetadata = unknown> {
@@ -609,7 +609,9 @@ export const SharedTreeAttributes: IChannelAttributes;
609
609
  export const SharedTreeFactoryType = "https://graph.microsoft.com/types/tree";
610
610
 
611
611
  // @beta @input
612
- export type SharedTreeOptionsBeta = ForestOptions & Partial<CodecWriteOptionsBeta>;
612
+ export interface SharedTreeOptionsBeta extends ForestOptions, Partial<CodecWriteOptionsBeta> {
613
+ readonly healUnresolvableIdentifiersOnDecode?: boolean;
614
+ }
613
615
 
614
616
  // @public @sealed @system
615
617
  export interface SimpleNodeSchemaBase<out TNodeKind extends NodeKind, out TCustomMetadata = unknown> {
@@ -17,6 +17,29 @@ export interface ChangeEncodingContext {
17
17
  readonly revision: RevisionTag | undefined;
18
18
  readonly idCompressor: IIdCompressor;
19
19
  readonly schema?: SchemaAndPolicy;
20
+ /**
21
+ * `true` when this context is encoding to or decoding from a summary blob.
22
+ * `false` when this context is for an op (or any other non-summary path,
23
+ * including utility encoders that aren't tied to persistence).
24
+ *
25
+ * @remarks
26
+ * Used to gate decode-time recovery behavior — for example, healing of
27
+ * unresolvable identifier IDs — that should only run when loading a
28
+ * (possibly broken) attach-summary blob, never when applying ops.
29
+ */
30
+ readonly isSummary: boolean;
31
+ /**
32
+ * If `true`, identifier values that the local id-compressor cannot resolve
33
+ * during decode are healed into deterministic stable UUIDs instead of
34
+ * throwing. See {@link FieldBatchEncodingContext.healUnresolvableIdentifiersOnDecode}.
35
+ * Only takes effect when `isSummary` is also `true`.
36
+ */
37
+ readonly healUnresolvableIdentifiersOnDecode?: boolean;
38
+ /**
39
+ * The SharedTree's shared-object id, used as input to the deterministic
40
+ * UUID derivation when {@link healUnresolvableIdentifiersOnDecode} triggers.
41
+ */
42
+ readonly sharedObjectId?: string;
20
43
  }
21
44
  export type ChangeFamilyCodec<TChange> = IJsonCodec<TChange, JsonCompatibleReadOnly, JsonCompatibleReadOnly, ChangeEncodingContext>;
22
45
  export interface ChangeFamilyEditor {
@@ -1 +1 @@
1
- {"version":3,"file":"changeFamily.d.ts","sourceRoot":"","sources":["../../../src/core/change-family/changeFamily.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE9E,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEnF,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,kBAAkB,EAAE,OAAO;IACxE,WAAW,CACV,eAAe,EAAE,MAAM,WAAW,EAClC,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,IAAI,GACrD,OAAO,CAAC;IAEX,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,MAAM,iBAAiB,CAAC,OAAO,IAAI,UAAU,CAClD,OAAO,EACP,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,CACrB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAClC;;;;;;;OAOG;IACH,gBAAgB,IAAI,IAAI,CAAC;IAEzB;;;;;;;OAOG;IACH,eAAe,IAAI,IAAI,CAAC;CACxB"}
1
+ {"version":3,"file":"changeFamily.d.ts","sourceRoot":"","sources":["../../../src/core/change-family/changeFamily.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE9E,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEnF,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,kBAAkB,EAAE,OAAO;IACxE,WAAW,CACV,eAAe,EAAE,MAAM,WAAW,EAClC,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,IAAI,GACrD,OAAO,CAAC;IAEX,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;;;;OASG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,mCAAmC,CAAC,EAAE,OAAO,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,iBAAiB,CAAC,OAAO,IAAI,UAAU,CAClD,OAAO,EACP,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,CACrB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAClC;;;;;;;OAOG;IACH,gBAAgB,IAAI,IAAI,CAAC;IAEzB;;;;;;;OAOG;IACH,eAAe,IAAI,IAAI,CAAC;CACxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"changeFamily.js","sourceRoot":"","sources":["../../../src/core/change-family/changeFamily.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IIdCompressor, SessionId } from \"@fluidframework/id-compressor\";\n\nimport type { ICodecFamily, IJsonCodec } from \"../../codec/index.js\";\nimport type { SchemaAndPolicy } from \"../../core/index.js\";\nimport type { JsonCompatibleReadOnly } from \"../../util/index.js\";\nimport type { ChangeRebaser, RevisionTag, TaggedChange } from \"../rebase/index.js\";\n\nexport interface ChangeFamily<TEditor extends ChangeFamilyEditor, TChange> {\n\tbuildEditor(\n\t\tmintRevisionTag: () => RevisionTag,\n\t\tchangeReceiver: (change: TaggedChange<TChange>) => void,\n\t): TEditor;\n\n\treadonly rebaser: ChangeRebaser<TChange>;\n\treadonly codecs: ICodecFamily<TChange, ChangeEncodingContext>;\n}\n\nexport interface ChangeEncodingContext {\n\treadonly originatorId: SessionId;\n\treadonly revision: RevisionTag | undefined;\n\treadonly idCompressor: IIdCompressor;\n\treadonly schema?: SchemaAndPolicy;\n}\n\nexport type ChangeFamilyCodec<TChange> = IJsonCodec<\n\tTChange,\n\tJsonCompatibleReadOnly,\n\tJsonCompatibleReadOnly,\n\tChangeEncodingContext\n>;\n\nexport interface ChangeFamilyEditor {\n\t/**\n\t * Must be called when a new transaction starts.\n\t *\n\t * Note: transactions are an optional feature. It is valid to make edits outside of a transaction.\n\t *\n\t * For each call to this function, a matching call to `exitTransaction` must be made at a later time.\n\t * Can be called repeatedly to indicate the start of nesting transactions.\n\t */\n\tenterTransaction(): void;\n\n\t/**\n\t * Must be called when a transaction ends.\n\t *\n\t * Note: transactions are an optional feature. It is valid to make edits outside of a transaction.\n\t *\n\t * For each call to this function, a matching call to `enterTransaction` must be made at an earlier time.\n\t * Can be called repeatedly to indicate the end of nesting transactions.\n\t */\n\texitTransaction(): void;\n}\n"]}
1
+ {"version":3,"file":"changeFamily.js","sourceRoot":"","sources":["../../../src/core/change-family/changeFamily.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IIdCompressor, SessionId } from \"@fluidframework/id-compressor\";\n\nimport type { ICodecFamily, IJsonCodec } from \"../../codec/index.js\";\nimport type { SchemaAndPolicy } from \"../../core/index.js\";\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- Referenced by doc comments\nimport type { FieldBatchEncodingContext } from \"../../feature-libraries/index.js\";\nimport type { JsonCompatibleReadOnly } from \"../../util/index.js\";\nimport type { ChangeRebaser, RevisionTag, TaggedChange } from \"../rebase/index.js\";\n\nexport interface ChangeFamily<TEditor extends ChangeFamilyEditor, TChange> {\n\tbuildEditor(\n\t\tmintRevisionTag: () => RevisionTag,\n\t\tchangeReceiver: (change: TaggedChange<TChange>) => void,\n\t): TEditor;\n\n\treadonly rebaser: ChangeRebaser<TChange>;\n\treadonly codecs: ICodecFamily<TChange, ChangeEncodingContext>;\n}\n\nexport interface ChangeEncodingContext {\n\treadonly originatorId: SessionId;\n\treadonly revision: RevisionTag | undefined;\n\treadonly idCompressor: IIdCompressor;\n\treadonly schema?: SchemaAndPolicy;\n\t/**\n\t * `true` when this context is encoding to or decoding from a summary blob.\n\t * `false` when this context is for an op (or any other non-summary path,\n\t * including utility encoders that aren't tied to persistence).\n\t *\n\t * @remarks\n\t * Used to gate decode-time recovery behavior — for example, healing of\n\t * unresolvable identifier IDs — that should only run when loading a\n\t * (possibly broken) attach-summary blob, never when applying ops.\n\t */\n\treadonly isSummary: boolean;\n\t/**\n\t * If `true`, identifier values that the local id-compressor cannot resolve\n\t * during decode are healed into deterministic stable UUIDs instead of\n\t * throwing. See {@link FieldBatchEncodingContext.healUnresolvableIdentifiersOnDecode}.\n\t * Only takes effect when `isSummary` is also `true`.\n\t */\n\treadonly healUnresolvableIdentifiersOnDecode?: boolean;\n\t/**\n\t * The SharedTree's shared-object id, used as input to the deterministic\n\t * UUID derivation when {@link healUnresolvableIdentifiersOnDecode} triggers.\n\t */\n\treadonly sharedObjectId?: string;\n}\n\nexport type ChangeFamilyCodec<TChange> = IJsonCodec<\n\tTChange,\n\tJsonCompatibleReadOnly,\n\tJsonCompatibleReadOnly,\n\tChangeEncodingContext\n>;\n\nexport interface ChangeFamilyEditor {\n\t/**\n\t * Must be called when a new transaction starts.\n\t *\n\t * Note: transactions are an optional feature. It is valid to make edits outside of a transaction.\n\t *\n\t * For each call to this function, a matching call to `exitTransaction` must be made at a later time.\n\t * Can be called repeatedly to indicate the start of nesting transactions.\n\t */\n\tenterTransaction(): void;\n\n\t/**\n\t * Must be called when a transaction ends.\n\t *\n\t * Note: transactions are an optional feature. It is valid to make edits outside of a transaction.\n\t *\n\t * For each call to this function, a matching call to `enterTransaction` must be made at an earlier time.\n\t * Can be called repeatedly to indicate the end of nesting transactions.\n\t */\n\texitTransaction(): void;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexCodecV1.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV1.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAEN,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,wBAAwB,EAAS,MAAM,8BAA8B,CAAC;AAgDpF,wBAAgB,8BAA8B,CAC7C,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,aAAa,GACzB,cAAc,CAAC,wBAAwB,CAAC,CAO1C"}
1
+ {"version":3,"file":"detachedFieldIndexCodecV1.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV1.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAEN,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,wBAAwB,EAAS,MAAM,8BAA8B,CAAC;AAkDpF,wBAAgB,8BAA8B,CAC7C,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,aAAa,GACzB,cAAc,CAAC,wBAAwB,CAAC,CAO1C"}
@@ -44,6 +44,8 @@ class MajorCodec {
44
44
  originatorId: this.revisionTagCodec.localSessionId,
45
45
  idCompressor: this.idCompressor,
46
46
  revision: undefined,
47
+ // DetachedFieldIndex codecs are only used by the summarizer.
48
+ isSummary: true,
47
49
  });
48
50
  }
49
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexCodecV1.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV1.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAI7D,kDAA4C;AAC5C,iDAK4B;AAE5B,yFAA+F;AAC/F,2FAAsF;AAGtF,MAAM,UAAU;IACf,YACkB,gBAAkC,EAClC,YAA2B;QAD3B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,iBAAY,GAAZ,YAAY,CAAe;IAC1C,CAAC;IAEG,MAAM,CAAC,KAAY;QACzB,IAAA,iBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/C;;;;;;;;;;;;;;;;WAgBG;QACH,IAAA,iBAAM,EACL,EAAE,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,EACxB,KAAK,CAAC,kEAAkE,CACxE,CAAC;QACF,OAAO,EAAE,CAAC;IACX,CAAC;IAEM,MAAM,CAAC,KAAyB;QACtC,IAAA,iBAAM,EACL,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,CAAC,EAC9B,KAAK,CAAC,kEAAkE,CACxE,CAAC;QACF,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,EAAE;YAC1C,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,cAAc;YAClD,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,QAAQ,EAAE,SAAS;SACnB,CAAC,CAAC;IACJ,CAAC;CACD;AAED,SAAgB,8BAA8B,CAC7C,gBAAkC,EAClC,YAA2B;IAE3B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAClE,OAAO,IAAA,4EAAyC,EAC/C,UAAU,EACV,IAAA,gBAAK,EAAC,mEAA+B,CAAC,EAAE,CAAC,EACzC,4BAAiB,CACjB,CAAC;AACH,CAAC;AAVD,wEAUC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nimport type { CodecAndSchema, IJsonCodec } from \"../../codec/index.js\";\nimport { brand } from \"../../util/index.js\";\nimport {\n\ttype EncodedRevisionTag,\n\ttype RevisionTagCodec,\n\ttype RevisionTag,\n\tRevisionTagSchema,\n} from \"../rebase/index.js\";\n\nimport { makeDetachedFieldIndexCodecFromMajorCodec } from \"./detachedFieldIndexCodecCommon.js\";\nimport { DetachedFieldIndexFormatVersion } from \"./detachedFieldIndexFormatCommon.js\";\nimport type { DetachedFieldSummaryData, Major } from \"./detachedFieldIndexTypes.js\";\n\nclass MajorCodec implements IJsonCodec<Major, EncodedRevisionTag> {\n\tpublic constructor(\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic encode(major: Major): EncodedRevisionTag {\n\t\tassert(major !== undefined, 0x88e /* Unexpected undefined revision */);\n\t\tconst id = this.revisionTagCodec.encode(major);\n\t\t/**\n\t\t * Preface: this codec is only used at summarization time (not for ops).\n\t\t * Note that the decode path must provide a session id in which to interpret the revision tag.\n\t\t * The revision associated with a detached root generally comes from the session which detaches that subtree,\n\t\t * which isn't generally the local session (nor is it available at decode time with the layering of the tree\n\t\t * package), despite decode using the local session id.\n\t\t *\n\t\t * This is made OK by enforcing that all ids on encode/decode are non-local, since local ids won't be interpretable\n\t\t * at decode time.\n\t\t * This assert is valid because the revision for an acked edit will have already been finalized, and a revision\n\t\t * for a local-only edit will be finalizable at summarization time (local edits can only occur on a summarizing client\n\t\t * if they're created while detached, and local ids made while detached are finalized before generating the attach summary).\n\t\t *\n\t\t * WARNING: the above is true when the whole container transitions from detached to attached,\n\t\t * but not when the container is already attached and it's just the shared-tree that is attaching.\n\t\t * The assert below will fail in such a scenario. This is addressed in the v2 codec.\n\t\t */\n\t\tassert(\n\t\t\tid === \"root\" || id >= 0,\n\t\t\t0x88f /* Expected final id on encode of detached field index revision */,\n\t\t);\n\t\treturn id;\n\t}\n\n\tpublic decode(major: EncodedRevisionTag): RevisionTag {\n\t\tassert(\n\t\t\tmajor === \"root\" || major >= 0,\n\t\t\t0x890 /* Expected final id on decode of detached field index revision */,\n\t\t);\n\t\treturn this.revisionTagCodec.decode(major, {\n\t\t\toriginatorId: this.revisionTagCodec.localSessionId,\n\t\t\tidCompressor: this.idCompressor,\n\t\t\trevision: undefined,\n\t\t});\n\t}\n}\n\nexport function makeDetachedNodeToFieldCodecV1(\n\trevisionTagCodec: RevisionTagCodec,\n\tidCompressor: IIdCompressor,\n): CodecAndSchema<DetachedFieldSummaryData> {\n\tconst majorCodec = new MajorCodec(revisionTagCodec, idCompressor);\n\treturn makeDetachedFieldIndexCodecFromMajorCodec(\n\t\tmajorCodec,\n\t\tbrand(DetachedFieldIndexFormatVersion.v1),\n\t\tRevisionTagSchema,\n\t);\n}\n"]}
1
+ {"version":3,"file":"detachedFieldIndexCodecV1.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV1.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAI7D,kDAA4C;AAC5C,iDAK4B;AAE5B,yFAA+F;AAC/F,2FAAsF;AAGtF,MAAM,UAAU;IACf,YACkB,gBAAkC,EAClC,YAA2B;QAD3B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,iBAAY,GAAZ,YAAY,CAAe;IAC1C,CAAC;IAEG,MAAM,CAAC,KAAY;QACzB,IAAA,iBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/C;;;;;;;;;;;;;;;;WAgBG;QACH,IAAA,iBAAM,EACL,EAAE,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,EACxB,KAAK,CAAC,kEAAkE,CACxE,CAAC;QACF,OAAO,EAAE,CAAC;IACX,CAAC;IAEM,MAAM,CAAC,KAAyB;QACtC,IAAA,iBAAM,EACL,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,CAAC,EAC9B,KAAK,CAAC,kEAAkE,CACxE,CAAC;QACF,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,EAAE;YAC1C,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,cAAc;YAClD,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,QAAQ,EAAE,SAAS;YACnB,6DAA6D;YAC7D,SAAS,EAAE,IAAI;SACf,CAAC,CAAC;IACJ,CAAC;CACD;AAED,SAAgB,8BAA8B,CAC7C,gBAAkC,EAClC,YAA2B;IAE3B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAClE,OAAO,IAAA,4EAAyC,EAC/C,UAAU,EACV,IAAA,gBAAK,EAAC,mEAA+B,CAAC,EAAE,CAAC,EACzC,4BAAiB,CACjB,CAAC;AACH,CAAC;AAVD,wEAUC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nimport type { CodecAndSchema, IJsonCodec } from \"../../codec/index.js\";\nimport { brand } from \"../../util/index.js\";\nimport {\n\ttype EncodedRevisionTag,\n\ttype RevisionTagCodec,\n\ttype RevisionTag,\n\tRevisionTagSchema,\n} from \"../rebase/index.js\";\n\nimport { makeDetachedFieldIndexCodecFromMajorCodec } from \"./detachedFieldIndexCodecCommon.js\";\nimport { DetachedFieldIndexFormatVersion } from \"./detachedFieldIndexFormatCommon.js\";\nimport type { DetachedFieldSummaryData, Major } from \"./detachedFieldIndexTypes.js\";\n\nclass MajorCodec implements IJsonCodec<Major, EncodedRevisionTag> {\n\tpublic constructor(\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic encode(major: Major): EncodedRevisionTag {\n\t\tassert(major !== undefined, 0x88e /* Unexpected undefined revision */);\n\t\tconst id = this.revisionTagCodec.encode(major);\n\t\t/**\n\t\t * Preface: this codec is only used at summarization time (not for ops).\n\t\t * Note that the decode path must provide a session id in which to interpret the revision tag.\n\t\t * The revision associated with a detached root generally comes from the session which detaches that subtree,\n\t\t * which isn't generally the local session (nor is it available at decode time with the layering of the tree\n\t\t * package), despite decode using the local session id.\n\t\t *\n\t\t * This is made OK by enforcing that all ids on encode/decode are non-local, since local ids won't be interpretable\n\t\t * at decode time.\n\t\t * This assert is valid because the revision for an acked edit will have already been finalized, and a revision\n\t\t * for a local-only edit will be finalizable at summarization time (local edits can only occur on a summarizing client\n\t\t * if they're created while detached, and local ids made while detached are finalized before generating the attach summary).\n\t\t *\n\t\t * WARNING: the above is true when the whole container transitions from detached to attached,\n\t\t * but not when the container is already attached and it's just the shared-tree that is attaching.\n\t\t * The assert below will fail in such a scenario. This is addressed in the v2 codec.\n\t\t */\n\t\tassert(\n\t\t\tid === \"root\" || id >= 0,\n\t\t\t0x88f /* Expected final id on encode of detached field index revision */,\n\t\t);\n\t\treturn id;\n\t}\n\n\tpublic decode(major: EncodedRevisionTag): RevisionTag {\n\t\tassert(\n\t\t\tmajor === \"root\" || major >= 0,\n\t\t\t0x890 /* Expected final id on decode of detached field index revision */,\n\t\t);\n\t\treturn this.revisionTagCodec.decode(major, {\n\t\t\toriginatorId: this.revisionTagCodec.localSessionId,\n\t\t\tidCompressor: this.idCompressor,\n\t\t\trevision: undefined,\n\t\t\t// DetachedFieldIndex codecs are only used by the summarizer.\n\t\t\tisSummary: true,\n\t\t});\n\t}\n}\n\nexport function makeDetachedNodeToFieldCodecV1(\n\trevisionTagCodec: RevisionTagCodec,\n\tidCompressor: IIdCompressor,\n): CodecAndSchema<DetachedFieldSummaryData> {\n\tconst majorCodec = new MajorCodec(revisionTagCodec, idCompressor);\n\treturn makeDetachedFieldIndexCodecFromMajorCodec(\n\t\tmajorCodec,\n\t\tbrand(DetachedFieldIndexFormatVersion.v1),\n\t\tRevisionTagSchema,\n\t);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexCodecV2.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV2.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,+BAA+B,CAAC;AAG7E,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAsB,gBAAgB,EAAe,MAAM,oBAAoB,CAAC;AAK5F,OAAO,KAAK,EAAE,wBAAwB,EAAS,MAAM,8BAA8B,CAAC;AAwCpF,wBAAgB,8BAA8B,CAC7C,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,aAAa,GACzB,cAAc,CAAC,wBAAwB,CAAC,CAO1C"}
1
+ {"version":3,"file":"detachedFieldIndexCodecV2.d.ts","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV2.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,+BAA+B,CAAC;AAG7E,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAsB,gBAAgB,EAAe,MAAM,oBAAoB,CAAC;AAK5F,OAAO,KAAK,EAAE,wBAAwB,EAAS,MAAM,8BAA8B,CAAC;AA0CpF,wBAAgB,8BAA8B,CAC7C,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,aAAa,GACzB,cAAc,CAAC,wBAAwB,CAAC,CAO1C"}
@@ -38,6 +38,8 @@ class MajorCodec {
38
38
  originatorId: this.revisionTagCodec.localSessionId,
39
39
  idCompressor: this.idCompressor,
40
40
  revision: undefined,
41
+ // DetachedFieldIndex codecs are only used by the summarizer.
42
+ isSummary: true,
41
43
  });
42
44
  }
43
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"detachedFieldIndexCodecV2.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV2.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAE7D,qEAAoE;AAKpE,yFAA+F;AAC/F,2FAAsF;AACtF,mFAA2E;AAG3E,MAAM,UAAU;IACf,YACkB,gBAAkC,EAClC,YAA2B;QAD3B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,iBAAY,GAAZ,YAAY,CAAe;IAC1C,CAAC;IAEG,MAAM,CAAC,KAAY;QACzB,IAAA,iBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE/C,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAC7B;;;eAGG;YACH,IAAA,iBAAM,EAAC,KAAK,KAAK,MAAM,EAAE,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACtE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACjD,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAEM,MAAM,CAAC,KAAoC;QACjD,IAAA,iBAAM,EACL,KAAK,KAAK,MAAM,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAA,qBAAU,EAAC,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAClF,KAAK,CAAC,mDAAmD,CACzD,CAAC;QACF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAA,qBAAU,EAAC,KAAK,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,EAAE;YAC1C,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,cAAc;YAClD,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,QAAQ,EAAE,SAAS;SACnB,CAAC,CAAC;IACJ,CAAC;CACD;AAED,SAAgB,8BAA8B,CAC7C,gBAAkC,EAClC,YAA2B;IAE3B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAClE,OAAO,IAAA,4EAAyC,EAC/C,UAAU,EACV,mEAA+B,CAAC,EAAE,EAClC,wDAAwB,CACxB,CAAC;AACH,CAAC;AAVD,wEAUC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor, StableId } from \"@fluidframework/id-compressor\";\nimport { isStableId } from \"@fluidframework/id-compressor/internal\";\n\nimport type { CodecAndSchema, IJsonCodec } from \"../../codec/index.js\";\nimport type { EncodedRevisionTag, RevisionTagCodec, RevisionTag } from \"../rebase/index.js\";\n\nimport { makeDetachedFieldIndexCodecFromMajorCodec } from \"./detachedFieldIndexCodecCommon.js\";\nimport { DetachedFieldIndexFormatVersion } from \"./detachedFieldIndexFormatCommon.js\";\nimport { StableOrFinalRevisionTag } from \"./detachedFieldIndexFormatV2.js\";\nimport type { DetachedFieldSummaryData, Major } from \"./detachedFieldIndexTypes.js\";\n\nclass MajorCodec implements IJsonCodec<Major> {\n\tpublic constructor(\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic encode(major: Major): EncodedRevisionTag | StableId {\n\t\tassert(major !== undefined, 0xbfb /* Unexpected undefined revision */);\n\t\tconst id = this.revisionTagCodec.encode(major);\n\n\t\tif (id !== \"root\" && id < 0) {\n\t\t\t/**\n\t\t\t * This code path handles the case where the major revision is not finalized.\n\t\t\t * This can happen the SharedTree is being attached to an already attached container.\n\t\t\t */\n\t\t\tassert(major !== \"root\", 0xbfc /* Major revision cannot be 'root' */);\n\t\t\tconst long = this.idCompressor.decompress(major);\n\t\t\treturn long;\n\t\t}\n\t\treturn id;\n\t}\n\n\tpublic decode(major: EncodedRevisionTag | StableId): RevisionTag {\n\t\tassert(\n\t\t\tmajor === \"root\" || (typeof major === \"string\" && isStableId(major)) || major >= 0,\n\t\t\t0xbfd /* Expected root, stable, or final compressed id */,\n\t\t);\n\t\tif (typeof major === \"string\" && isStableId(major)) {\n\t\t\treturn this.idCompressor.recompress(major);\n\t\t}\n\t\treturn this.revisionTagCodec.decode(major, {\n\t\t\toriginatorId: this.revisionTagCodec.localSessionId,\n\t\t\tidCompressor: this.idCompressor,\n\t\t\trevision: undefined,\n\t\t});\n\t}\n}\n\nexport function makeDetachedNodeToFieldCodecV2(\n\trevisionTagCodec: RevisionTagCodec,\n\tidCompressor: IIdCompressor,\n): CodecAndSchema<DetachedFieldSummaryData> {\n\tconst majorCodec = new MajorCodec(revisionTagCodec, idCompressor);\n\treturn makeDetachedFieldIndexCodecFromMajorCodec(\n\t\tmajorCodec,\n\t\tDetachedFieldIndexFormatVersion.v2,\n\t\tStableOrFinalRevisionTag,\n\t);\n}\n"]}
1
+ {"version":3,"file":"detachedFieldIndexCodecV2.js","sourceRoot":"","sources":["../../../src/core/tree/detachedFieldIndexCodecV2.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAE7D,qEAAoE;AAKpE,yFAA+F;AAC/F,2FAAsF;AACtF,mFAA2E;AAG3E,MAAM,UAAU;IACf,YACkB,gBAAkC,EAClC,YAA2B;QAD3B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,iBAAY,GAAZ,YAAY,CAAe;IAC1C,CAAC;IAEG,MAAM,CAAC,KAAY;QACzB,IAAA,iBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE/C,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAC7B;;;eAGG;YACH,IAAA,iBAAM,EAAC,KAAK,KAAK,MAAM,EAAE,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACtE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACjD,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAEM,MAAM,CAAC,KAAoC;QACjD,IAAA,iBAAM,EACL,KAAK,KAAK,MAAM,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAA,qBAAU,EAAC,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAClF,KAAK,CAAC,mDAAmD,CACzD,CAAC;QACF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAA,qBAAU,EAAC,KAAK,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,EAAE;YAC1C,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,cAAc;YAClD,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,QAAQ,EAAE,SAAS;YACnB,6DAA6D;YAC7D,SAAS,EAAE,IAAI;SACf,CAAC,CAAC;IACJ,CAAC;CACD;AAED,SAAgB,8BAA8B,CAC7C,gBAAkC,EAClC,YAA2B;IAE3B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAClE,OAAO,IAAA,4EAAyC,EAC/C,UAAU,EACV,mEAA+B,CAAC,EAAE,EAClC,wDAAwB,CACxB,CAAC;AACH,CAAC;AAVD,wEAUC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor, StableId } from \"@fluidframework/id-compressor\";\nimport { isStableId } from \"@fluidframework/id-compressor/internal\";\n\nimport type { CodecAndSchema, IJsonCodec } from \"../../codec/index.js\";\nimport type { EncodedRevisionTag, RevisionTagCodec, RevisionTag } from \"../rebase/index.js\";\n\nimport { makeDetachedFieldIndexCodecFromMajorCodec } from \"./detachedFieldIndexCodecCommon.js\";\nimport { DetachedFieldIndexFormatVersion } from \"./detachedFieldIndexFormatCommon.js\";\nimport { StableOrFinalRevisionTag } from \"./detachedFieldIndexFormatV2.js\";\nimport type { DetachedFieldSummaryData, Major } from \"./detachedFieldIndexTypes.js\";\n\nclass MajorCodec implements IJsonCodec<Major> {\n\tpublic constructor(\n\t\tprivate readonly revisionTagCodec: RevisionTagCodec,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic encode(major: Major): EncodedRevisionTag | StableId {\n\t\tassert(major !== undefined, 0xbfb /* Unexpected undefined revision */);\n\t\tconst id = this.revisionTagCodec.encode(major);\n\n\t\tif (id !== \"root\" && id < 0) {\n\t\t\t/**\n\t\t\t * This code path handles the case where the major revision is not finalized.\n\t\t\t * This can happen the SharedTree is being attached to an already attached container.\n\t\t\t */\n\t\t\tassert(major !== \"root\", 0xbfc /* Major revision cannot be 'root' */);\n\t\t\tconst long = this.idCompressor.decompress(major);\n\t\t\treturn long;\n\t\t}\n\t\treturn id;\n\t}\n\n\tpublic decode(major: EncodedRevisionTag | StableId): RevisionTag {\n\t\tassert(\n\t\t\tmajor === \"root\" || (typeof major === \"string\" && isStableId(major)) || major >= 0,\n\t\t\t0xbfd /* Expected root, stable, or final compressed id */,\n\t\t);\n\t\tif (typeof major === \"string\" && isStableId(major)) {\n\t\t\treturn this.idCompressor.recompress(major);\n\t\t}\n\t\treturn this.revisionTagCodec.decode(major, {\n\t\t\toriginatorId: this.revisionTagCodec.localSessionId,\n\t\t\tidCompressor: this.idCompressor,\n\t\t\trevision: undefined,\n\t\t\t// DetachedFieldIndex codecs are only used by the summarizer.\n\t\t\tisSummary: true,\n\t\t});\n\t}\n}\n\nexport function makeDetachedNodeToFieldCodecV2(\n\trevisionTagCodec: RevisionTagCodec,\n\tidCompressor: IIdCompressor,\n): CodecAndSchema<DetachedFieldSummaryData> {\n\tconst majorCodec = new MajorCodec(revisionTagCodec, idCompressor);\n\treturn makeDetachedFieldIndexCodecFromMajorCodec(\n\t\tmajorCodec,\n\t\tDetachedFieldIndexFormatVersion.v2,\n\t\tStableOrFinalRevisionTag,\n\t);\n}\n"]}
@@ -96,10 +96,27 @@ export declare class BasicChunkCursor extends SynchronousCursor implements Chunk
96
96
  atChunkRoot(): boolean;
97
97
  fork(): BasicChunkCursor;
98
98
  get mode(): CursorLocationType;
99
+ /**
100
+ * Asserts that the node-only stacks (`indexOfChunkStack` and `indexWithinChunkStack`) are in sync with `siblingStack`.
101
+ * Since `siblingStack` interleaves field and node levels while the node-only stacks are pushed/popped only on node-level transitions,
102
+ * their length should always equal the number of node levels traversed.
103
+ */
104
+ private assertChunkStacksMatchNodeDepth;
99
105
  getFieldKey(): FieldKey;
100
106
  private getStackedFieldKey;
101
107
  private getStackedNodeIndex;
102
- private getStackedNode;
108
+ private getStackedChunkIndex;
109
+ private getStackedChunk;
110
+ /**
111
+ * Converts a {@link height}, which contains field and node levels, into the corresponding depth/index
112
+ * for the node-only stacks ({@link indexOfChunkStack} and {@link indexWithinChunkStack}), which are
113
+ * only pushed on node-level transitions.
114
+ *
115
+ * @param height - A depth in {@link siblingStack} to convert. Defaults to {@link siblingStack}'s
116
+ * current length, which gives the current depth of the node-only stacks.
117
+ * @returns `floor(height / 2)` — the number of node levels at or below the given stack height.
118
+ */
119
+ private getNodeOnlyHeightFromHeight;
103
120
  getFieldLength(): number;
104
121
  enterNode(index: number): void;
105
122
  getPath(prefix?: PathRootPrefix): UpPath;
@@ -116,6 +133,13 @@ export declare class BasicChunkCursor extends SynchronousCursor implements Chunk
116
133
  exitField(): void;
117
134
  exitNode(): void;
118
135
  private getNode;
136
+ /**
137
+ * Resolves the chunks that make up the field the cursor is currently in. At the root, this is
138
+ * {@link root} directly. Otherwise, the cursor must be in {@link CursorLocationType.Fields} mode,
139
+ * and the result is looked up on the parent node using the current field key.
140
+ *
141
+ * @returns The chunks that make up the field the cursor is currently in.
142
+ */
119
143
  private getField;
120
144
  get value(): Value;
121
145
  get type(): TreeType;
@@ -1 +1 @@
1
- {"version":3,"file":"basicChunk.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/basicChunk.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,kBAAkB,EAClB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,WAAW,EAEX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAc,MAAM,uBAAuB,CAAC;AAEtE;;GAEG;AACH,qBAAa,UAAW,SAAQ,oBAAqB,YAAW,SAAS;IAShE,IAAI,EAAE,wBAAwB;IACrC;;;;;;;OAOG;IACI,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;IACzC;;OAEG;IACI,KAAK,CAAC;IArBd,SAAgB,cAAc,EAAE,MAAM,CAAK;IAE3C;;;;OAIG;gBAEK,IAAI,EAAE,wBAAwB;IACrC;;;;;;;OAOG;IACI,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;IACzC;;OAEG;IACI,KAAK,CAAC,uBAAW;IAKlB,KAAK,IAAI,UAAU;IAYnB,MAAM,IAAI,aAAa;IAI9B,SAAS,CAAC,cAAc,IAAI,IAAI;CAOhC;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,SAAS,EAAE,GAAG,SAAS,QAAQ,EAAE,CAAC;AAEvE;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAiB,SAAQ,iBAAkB,YAAW,aAAa;IAsB9E,SAAS,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE;IACpC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,EAAE;IAChD,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE;IACvC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE;IAG9C,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,EAAE;IAClD,SAAS,CAAC,QAAQ,EAAE,aAAa;IACjC,SAAS,CAAC,KAAK,EAAE,MAAM;IACvB,SAAS,CAAC,YAAY,EAAE,MAAM;IAC9B,SAAS,CAAC,gBAAgB,EAAE,MAAM;IAClC,SAAS,CAAC,YAAY,EAAE,aAAa,GAAG,SAAS;IAhClD;;;;;;;;;;;;;;;;;;;OAmBG;gBAEQ,IAAI,EAAE,SAAS,SAAS,EAAE,EACjB,YAAY,EAAE,aAAa,EAAE,EAC7B,UAAU,EAAE,MAAM,EAAE,EACpB,iBAAiB,EAAE,MAAM,EAAE,EAG3B,qBAAqB,EAAE,MAAM,EAAE,EACxC,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,aAAa,GAAG,SAAS;IAKlD,IAAW,CAAC,WAAW,CAAC,IAAI,SAAS,GAAG,SAAS,CAMhD;IAEM,WAAW,IAAI,OAAO;IAOtB,IAAI,IAAI,gBAAgB;IAiB/B,IAAW,IAAI,IAAI,kBAAkB,CAmBpC;IAEM,WAAW,IAAI,QAAQ;IAQ9B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,cAAc;IAKf,cAAc,IAAI,MAAM;IAaxB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS9B,OAAO,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM;IAa/C,OAAO,CAAC,gBAAgB;IAYjB,YAAY,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,WAAW;IAczD,OAAO,CAAC,aAAa;IA6Cd,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAkB/B,SAAS,IAAI,OAAO;IAYpB,UAAU,IAAI,OAAO;IAgBrB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAoDlC,SAAS,IAAI,OAAO;IAoBpB,QAAQ,IAAI,OAAO;IAiC1B,OAAO,CAAC,gBAAgB;IAUjB,SAAS,IAAI,IAAI;IAajB,QAAQ,IAAI,IAAI;IAqBvB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,QAAQ;IAchB,IAAW,KAAK,IAAI,KAAK,CAKxB;IAED,IAAW,IAAI,IAAI,QAAQ,CAK1B;IAED,IAAW,UAAU,IAAI,MAAM,CAa9B;IAED;;;OAGG;IACH,OAAO,CAAC,YAAY;IAUpB,IAAW,UAAU,IAAI,MAAM,CAQ9B;IAED,IAAW,WAAW,IAAI,MAAM,CAK/B;CACD"}
1
+ {"version":3,"file":"basicChunk.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/chunked-forest/basicChunk.ts"],"names":[],"mappings":"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"}
@@ -130,16 +130,21 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
130
130
  if (this.nestedCursor !== undefined) {
131
131
  return this.nestedCursor.mode;
132
132
  }
133
- // Compute the number of nodes deep the current depth is.
134
- // We want the floor of the result, which can computed using a bitwise shift assuming the depth is less than 2^31, which seems safe.
135
- // eslint-disable-next-line no-bitwise
136
- const halfHeight = (this.siblingStack.length + 1) >> 1;
137
- (0, internal_1.assert)(this.indexOfChunkStack.length === halfHeight, 0x51c /* unexpected indexOfChunkStack */);
138
- (0, internal_1.assert)(this.indexWithinChunkStack.length === halfHeight, 0x51d /* unexpected indexWithinChunkStack */);
133
+ this.assertChunkStacksMatchNodeDepth();
139
134
  return this.siblingStack.length % 2 === 0
140
135
  ? 1 /* CursorLocationType.Fields */
141
136
  : 0 /* CursorLocationType.Nodes */;
142
137
  }
138
+ /**
139
+ * Asserts that the node-only stacks (`indexOfChunkStack` and `indexWithinChunkStack`) are in sync with `siblingStack`.
140
+ * Since `siblingStack` interleaves field and node levels while the node-only stacks are pushed/popped only on node-level transitions,
141
+ * their length should always equal the number of node levels traversed.
142
+ */
143
+ assertChunkStacksMatchNodeDepth() {
144
+ const halfHeight = this.getNodeOnlyHeightFromHeight();
145
+ (0, internal_1.assert)(this.indexOfChunkStack.length === halfHeight, 0x51c /* unexpected indexOfChunkStack */);
146
+ (0, internal_1.assert)(this.indexWithinChunkStack.length === halfHeight, 0x51d /* unexpected indexWithinChunkStack */);
147
+ }
143
148
  getFieldKey() {
144
149
  if (this.nestedCursor !== undefined) {
145
150
  return this.nestedCursor.getFieldKey();
@@ -157,9 +162,30 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
157
162
  (0, internal_1.assert)(height >= 0, 0x521 /* must not be above root */);
158
163
  return this.indexStack[height] ?? (0, internal_1.oob)();
159
164
  }
160
- getStackedNode(height) {
161
- const index = this.getStackedNodeIndex(height);
162
- return this.siblingStack[height][index];
165
+ getStackedChunkIndex(height) {
166
+ (0, internal_1.assert)(height % 2 === 1, 0xcf3 /* must be node height */);
167
+ (0, internal_1.assert)(height >= 0, 0xcf4 /* must not be above root */);
168
+ return this.indexOfChunkStack[this.getNodeOnlyHeightFromHeight(height)] ?? (0, internal_1.oob)();
169
+ }
170
+ getStackedChunk(height) {
171
+ const index = this.getStackedChunkIndex(height);
172
+ const chunk = this.siblingStack[height][index];
173
+ (0, internal_1.debugAssert)(() => chunk instanceof BasicChunk || "only basic chunks are expected");
174
+ return chunk;
175
+ }
176
+ /**
177
+ * Converts a {@link height}, which contains field and node levels, into the corresponding depth/index
178
+ * for the node-only stacks ({@link indexOfChunkStack} and {@link indexWithinChunkStack}), which are
179
+ * only pushed on node-level transitions.
180
+ *
181
+ * @param height - A depth in {@link siblingStack} to convert. Defaults to {@link siblingStack}'s
182
+ * current length, which gives the current depth of the node-only stacks.
183
+ * @returns `floor(height / 2)` — the number of node levels at or below the given stack height.
184
+ */
185
+ getNodeOnlyHeightFromHeight(height = this.siblingStack.length) {
186
+ // The bitwise shift computes the floor, which is valid assuming the depth is less than 2^31, which seems safe.
187
+ // eslint-disable-next-line no-bitwise
188
+ return height >> 1;
163
189
  }
164
190
  getFieldLength() {
165
191
  if (this.nestedCursor !== undefined) {
@@ -256,6 +282,11 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
256
282
  (0, internal_1.assert)(this.mode === 0 /* CursorLocationType.Nodes */, 0x528 /* must be in nodes mode */);
257
283
  this.siblingStack.push(this.siblings);
258
284
  this.indexStack.push(this.index);
285
+ // Save the chunk array position of the current node. When siblings contain
286
+ // multi node chunks, the flat node index diverges from the array position,
287
+ // so getField needs this to locate the parent in the sibling array.
288
+ this.indexOfChunkStack.push(this.indexOfChunk);
289
+ this.indexWithinChunkStack.push(this.indexWithinChunk);
259
290
  // For fields, siblings are only used for key lookup and
260
291
  // nextField and which has arbitrary iteration order,
261
292
  // so making a array of just key here works.
@@ -263,6 +294,7 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
263
294
  // at the cost of an allocation here.
264
295
  this.index = 0;
265
296
  this.siblings = [key];
297
+ this.assertChunkStacksMatchNodeDepth();
266
298
  }
267
299
  nextField() {
268
300
  if (this.nestedCursor !== undefined) {
@@ -285,8 +317,11 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
285
317
  }
286
318
  this.siblingStack.push(this.siblings);
287
319
  this.indexStack.push(this.index);
320
+ this.indexOfChunkStack.push(this.indexOfChunk);
321
+ this.indexWithinChunkStack.push(this.indexWithinChunk);
288
322
  this.index = 0;
289
323
  this.siblings = [...fields.keys()]; // TODO: avoid this copy
324
+ this.assertChunkStacksMatchNodeDepth();
290
325
  return true;
291
326
  }
292
327
  seekNodes(offset) {
@@ -343,12 +378,11 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
343
378
  }
344
379
  this.siblingStack.push(this.siblings);
345
380
  this.indexStack.push(this.index);
346
- this.indexOfChunkStack.push(this.indexOfChunk);
347
- this.indexWithinChunkStack.push(this.indexWithinChunk);
348
381
  this.index = 0;
349
382
  this.siblings = siblings;
350
383
  this.indexOfChunk = 0;
351
384
  this.indexWithinChunk = 0;
385
+ this.assertChunkStacksMatchNodeDepth();
352
386
  this.initNestedCursor();
353
387
  return true;
354
388
  }
@@ -393,6 +427,12 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
393
427
  this.siblings =
394
428
  this.siblingStack.pop() ?? (0, internal_1.fail)(0xaf0 /* Unexpected siblingStack.length */);
395
429
  this.index = this.indexStack.pop() ?? (0, internal_1.fail)(0xaf1 /* Unexpected indexStack.length */);
430
+ this.indexOfChunk =
431
+ this.indexOfChunkStack.pop() ?? (0, internal_1.fail)(0xcf5 /* Unexpected indexOfChunkStack.length */);
432
+ this.indexWithinChunk =
433
+ this.indexWithinChunkStack.pop() ??
434
+ (0, internal_1.fail)(0xcf6 /* Unexpected indexWithinChunkStack.length */);
435
+ this.assertChunkStacksMatchNodeDepth();
396
436
  }
397
437
  exitNode() {
398
438
  if (this.nestedCursor !== undefined) {
@@ -405,22 +445,35 @@ class BasicChunkCursor extends treeCursorUtils_js_1.SynchronousCursor {
405
445
  this.siblings =
406
446
  this.siblingStack.pop() ?? (0, internal_1.fail)(0xaf2 /* Unexpected siblingStack.length */);
407
447
  this.index = this.indexStack.pop() ?? (0, internal_1.fail)(0xaf3 /* Unexpected indexStack.length */);
408
- this.indexOfChunk =
409
- this.indexOfChunkStack.pop() ?? (0, internal_1.fail)(0xaf4 /* Unexpected indexOfChunkStack.length */);
410
- this.indexWithinChunk =
411
- this.indexWithinChunkStack.pop() ??
412
- (0, internal_1.fail)(0xaf5 /* Unexpected indexWithinChunkStack.length */);
448
+ // At the Fields level these aren't semantically used, but reset for consistent state
449
+ // (so a fully-iterated cursor matches a fresh cursor at the same logical position).
450
+ this.indexOfChunk = 0;
451
+ this.indexWithinChunk = 0;
452
+ this.assertChunkStacksMatchNodeDepth();
413
453
  }
414
454
  getNode() {
415
455
  (0, internal_1.assert)(this.mode === 0 /* CursorLocationType.Nodes */, 0x52f /* can only get node when in node */);
416
- return this.siblings[this.index];
456
+ const chunk = this.siblings[this.indexOfChunk];
457
+ (0, internal_1.debugAssert)(() => chunk instanceof BasicChunk || "only basic chunks are expected");
458
+ return chunk;
417
459
  }
460
+ /**
461
+ * Resolves the chunks that make up the field the cursor is currently in. At the root, this is
462
+ * {@link root} directly. Otherwise, the cursor must be in {@link CursorLocationType.Fields} mode,
463
+ * and the result is looked up on the parent node using the current field key.
464
+ *
465
+ * @returns The chunks that make up the field the cursor is currently in.
466
+ */
418
467
  getField() {
419
468
  if (this.siblingStack.length === 0) {
420
469
  return this.root;
421
470
  }
422
471
  (0, internal_1.assert)(this.mode === 1 /* CursorLocationType.Fields */, 0x530 /* can only get field when in fields */);
423
- const parent = this.getStackedNode(this.indexStack.length - 1);
472
+ // The parent node is the `BasicChunk` in the node array at the top of
473
+ // `siblingStack` while we are in `CursorLocationType.Fields` mode. We need the parent
474
+ // since a field's chunks are stored on the parent node's `BasicChunk.fields` map, not on
475
+ // the cursor itself.
476
+ const parent = this.getStackedChunk(this.siblingStack.length - 1);
424
477
  const key = this.getFieldKey();
425
478
  const field = parent.fields.get(key) ?? [];
426
479
  return field;