@fluidframework/tree 2.74.0 → 2.81.0-374083

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 (1318) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/api-report/tree.alpha.api.md +63 -9
  3. package/dist/alpha.d.ts +9 -0
  4. package/dist/codec/codec.d.ts +31 -3
  5. package/dist/codec/codec.d.ts.map +1 -1
  6. package/dist/codec/codec.js +10 -0
  7. package/dist/codec/codec.js.map +1 -1
  8. package/dist/codec/index.d.ts +2 -2
  9. package/dist/codec/index.d.ts.map +1 -1
  10. package/dist/codec/index.js +2 -2
  11. package/dist/codec/index.js.map +1 -1
  12. package/dist/codec/versioned/codec.d.ts +80 -22
  13. package/dist/codec/versioned/codec.d.ts.map +1 -1
  14. package/dist/codec/versioned/codec.js +137 -15
  15. package/dist/codec/versioned/codec.js.map +1 -1
  16. package/dist/codec/versioned/index.d.ts +1 -1
  17. package/dist/codec/versioned/index.d.ts.map +1 -1
  18. package/dist/codec/versioned/index.js +2 -2
  19. package/dist/codec/versioned/index.js.map +1 -1
  20. package/dist/core/change-family/changeFamily.d.ts +4 -1
  21. package/dist/core/change-family/changeFamily.d.ts.map +1 -1
  22. package/dist/core/change-family/changeFamily.js.map +1 -1
  23. package/dist/core/change-family/index.d.ts +1 -1
  24. package/dist/core/change-family/index.d.ts.map +1 -1
  25. package/dist/core/change-family/index.js.map +1 -1
  26. package/dist/core/index.d.ts +3 -3
  27. package/dist/core/index.d.ts.map +1 -1
  28. package/dist/core/index.js +7 -6
  29. package/dist/core/index.js.map +1 -1
  30. package/dist/core/rebase/changeRebaser.d.ts +42 -3
  31. package/dist/core/rebase/changeRebaser.d.ts.map +1 -1
  32. package/dist/core/rebase/changeRebaser.js.map +1 -1
  33. package/dist/core/rebase/index.d.ts +2 -2
  34. package/dist/core/rebase/index.d.ts.map +1 -1
  35. package/dist/core/rebase/index.js +2 -2
  36. package/dist/core/rebase/index.js.map +1 -1
  37. package/dist/core/rebase/types.d.ts +52 -10
  38. package/dist/core/rebase/types.d.ts.map +1 -1
  39. package/dist/core/rebase/types.js +5 -12
  40. package/dist/core/rebase/types.js.map +1 -1
  41. package/dist/core/rebase/utils.d.ts.map +1 -1
  42. package/dist/core/rebase/utils.js +33 -11
  43. package/dist/core/rebase/utils.js.map +1 -1
  44. package/dist/core/schema-stored/schema.js +3 -3
  45. package/dist/core/schema-stored/schema.js.map +1 -1
  46. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  47. package/dist/core/tree/anchorSet.js +4 -4
  48. package/dist/core/tree/anchorSet.js.map +1 -1
  49. package/dist/core/tree/detachedFieldIndex.d.ts +7 -2
  50. package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
  51. package/dist/core/tree/detachedFieldIndex.js +21 -56
  52. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  53. package/dist/core/tree/detachedFieldIndexCodecCommon.d.ts +18 -10
  54. package/dist/core/tree/detachedFieldIndexCodecCommon.d.ts.map +1 -1
  55. package/dist/core/tree/detachedFieldIndexCodecCommon.js +6 -6
  56. package/dist/core/tree/detachedFieldIndexCodecCommon.js.map +1 -1
  57. package/dist/core/tree/detachedFieldIndexCodecV1.d.ts +2 -3
  58. package/dist/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
  59. package/dist/core/tree/detachedFieldIndexCodecV1.js +4 -5
  60. package/dist/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
  61. package/dist/core/tree/detachedFieldIndexCodecV2.d.ts +2 -3
  62. package/dist/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
  63. package/dist/core/tree/detachedFieldIndexCodecV2.js +4 -6
  64. package/dist/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
  65. package/dist/core/tree/detachedFieldIndexCodecs.d.ts +5 -6
  66. package/dist/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
  67. package/dist/core/tree/detachedFieldIndexCodecs.js +11 -41
  68. package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
  69. package/dist/core/tree/index.d.ts +2 -2
  70. package/dist/core/tree/index.d.ts.map +1 -1
  71. package/dist/core/tree/index.js +5 -4
  72. package/dist/core/tree/index.js.map +1 -1
  73. package/dist/core/tree/mapTree.js +1 -1
  74. package/dist/core/tree/mapTree.js.map +1 -1
  75. package/dist/core/tree/pathTree.d.ts +11 -3
  76. package/dist/core/tree/pathTree.d.ts.map +1 -1
  77. package/dist/core/tree/pathTree.js +14 -2
  78. package/dist/core/tree/pathTree.js.map +1 -1
  79. package/dist/core/tree/sparseTree.d.ts.map +1 -1
  80. package/dist/core/tree/sparseTree.js +1 -0
  81. package/dist/core/tree/sparseTree.js.map +1 -1
  82. package/dist/core/tree/treeTextFormat.d.ts.map +1 -1
  83. package/dist/core/tree/treeTextFormat.js +5 -9
  84. package/dist/core/tree/treeTextFormat.js.map +1 -1
  85. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  86. package/dist/core/tree/visitDelta.js +3 -2
  87. package/dist/core/tree/visitDelta.js.map +1 -1
  88. package/dist/core/tree/visitorUtils.d.ts.map +1 -1
  89. package/dist/core/tree/visitorUtils.js +58 -18
  90. package/dist/core/tree/visitorUtils.js.map +1 -1
  91. package/dist/feature-libraries/changeAtomIdBTree.d.ts +16 -0
  92. package/dist/feature-libraries/changeAtomIdBTree.d.ts.map +1 -0
  93. package/dist/feature-libraries/changeAtomIdBTree.js +30 -0
  94. package/dist/feature-libraries/changeAtomIdBTree.js.map +1 -0
  95. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  96. package/dist/feature-libraries/chunked-forest/basicChunk.js +8 -1
  97. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  98. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  99. package/dist/feature-libraries/chunked-forest/chunkTree.js +4 -1
  100. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  101. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  102. package/dist/feature-libraries/chunked-forest/chunkedForest.js +9 -7
  103. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  104. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  105. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +7 -4
  106. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  107. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  108. package/dist/feature-libraries/chunked-forest/codec/codecs.js +19 -11
  109. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  110. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
  111. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  112. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +9 -5
  113. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  114. package/dist/feature-libraries/chunked-forest/uniformChunk.js +1 -1
  115. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  116. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +103 -44
  117. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  118. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +251 -77
  119. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  120. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -1
  121. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  122. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +22 -3
  123. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  124. package/dist/feature-libraries/default-schema/index.d.ts +2 -1
  125. package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
  126. package/dist/feature-libraries/default-schema/index.js +5 -2
  127. package/dist/feature-libraries/default-schema/index.js.map +1 -1
  128. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +38 -0
  129. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +1 -0
  130. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js +132 -0
  131. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js.map +1 -0
  132. package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts +9 -6
  133. package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
  134. package/dist/feature-libraries/default-schema/mappedEditBuilder.js +21 -0
  135. package/dist/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
  136. package/dist/feature-libraries/deltaUtils.d.ts +1 -0
  137. package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
  138. package/dist/feature-libraries/deltaUtils.js +6 -1
  139. package/dist/feature-libraries/deltaUtils.js.map +1 -1
  140. package/dist/feature-libraries/flex-tree/context.d.ts +9 -0
  141. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  142. package/dist/feature-libraries/flex-tree/context.js +6 -0
  143. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  144. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
  145. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  146. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  147. package/dist/feature-libraries/flex-tree/lazyField.d.ts +8 -7
  148. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  149. package/dist/feature-libraries/flex-tree/lazyField.js +44 -15
  150. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  151. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  152. package/dist/feature-libraries/forest-summary/forestSummarizer.js +3 -1
  153. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  154. package/dist/feature-libraries/index.d.ts +5 -4
  155. package/dist/feature-libraries/index.d.ts.map +1 -1
  156. package/dist/feature-libraries/index.js +15 -8
  157. package/dist/feature-libraries/index.js.map +1 -1
  158. package/dist/feature-libraries/indexing/anchorTreeIndex.js +6 -6
  159. package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  160. package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
  161. package/dist/feature-libraries/mapTreeCursor.js +1 -0
  162. package/dist/feature-libraries/mapTreeCursor.js.map +1 -1
  163. package/dist/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
  164. package/dist/feature-libraries/mitigatedChangeFamily.js +12 -3
  165. package/dist/feature-libraries/mitigatedChangeFamily.js.map +1 -1
  166. package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  167. package/dist/feature-libraries/modular-schema/comparison.js +12 -9
  168. package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
  169. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +97 -21
  170. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  171. package/dist/feature-libraries/modular-schema/crossFieldQueries.js +4 -7
  172. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  173. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +25 -0
  174. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -0
  175. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js +59 -0
  176. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -0
  177. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +22 -53
  178. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  179. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  180. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  181. package/dist/feature-libraries/modular-schema/genericFieldKind.js +7 -13
  182. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  183. package/dist/feature-libraries/modular-schema/genericFieldKindCodecs.js +2 -2
  184. package/dist/feature-libraries/modular-schema/genericFieldKindCodecs.js.map +1 -1
  185. package/dist/feature-libraries/modular-schema/index.d.ts +7 -5
  186. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  187. package/dist/feature-libraries/modular-schema/index.js +12 -8
  188. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  189. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +32 -0
  190. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -0
  191. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +409 -0
  192. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -0
  193. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +15 -0
  194. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -0
  195. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js +31 -0
  196. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -0
  197. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.d.ts +15 -0
  198. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.d.ts.map +1 -0
  199. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.js +393 -0
  200. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.js.map +1 -0
  201. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
  202. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  203. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +32 -288
  204. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  205. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +60 -26
  206. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  207. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1519 -615
  208. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  209. package/{lib/feature-libraries/modular-schema/modularChangeFormat.d.ts → dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts} +5 -6
  210. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -0
  211. package/dist/feature-libraries/modular-schema/{modularChangeFormat.js → modularChangeFormatV1.js} +7 -7
  212. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -0
  213. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +112 -0
  214. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -0
  215. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +21 -0
  216. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -0
  217. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.d.ts +146 -0
  218. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.d.ts.map +1 -0
  219. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.js +32 -0
  220. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.js.map +1 -0
  221. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +59 -13
  222. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  223. package/dist/feature-libraries/modular-schema/modularChangeTypes.js +3 -3
  224. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  225. package/dist/feature-libraries/node-identifier/mockNodeIdentifierManager.js +1 -1
  226. package/dist/feature-libraries/node-identifier/mockNodeIdentifierManager.js.map +1 -1
  227. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  228. package/dist/feature-libraries/object-forest/objectForest.js +7 -5
  229. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  230. package/dist/feature-libraries/optional-field/index.d.ts +2 -2
  231. package/dist/feature-libraries/optional-field/index.d.ts.map +1 -1
  232. package/dist/feature-libraries/optional-field/index.js +1 -2
  233. package/dist/feature-libraries/optional-field/index.js.map +1 -1
  234. package/dist/feature-libraries/optional-field/optionalField.d.ts +5 -26
  235. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  236. package/dist/feature-libraries/optional-field/optionalField.js +223 -450
  237. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  238. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +23 -0
  239. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +1 -0
  240. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +31 -0
  241. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +1 -0
  242. package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +24 -33
  243. package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
  244. package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
  245. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
  246. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
  247. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js +57 -28
  248. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
  249. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +12 -0
  250. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +1 -0
  251. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js +57 -0
  252. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js.map +1 -0
  253. package/dist/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
  254. package/dist/feature-libraries/optional-field/optionalFieldCodecs.js +5 -1
  255. package/dist/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
  256. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
  257. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js +14 -2
  258. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
  259. package/dist/feature-libraries/schema-index/codec.d.ts +7 -21
  260. package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
  261. package/dist/feature-libraries/schema-index/codec.js +28 -70
  262. package/dist/feature-libraries/schema-index/codec.js.map +1 -1
  263. package/dist/feature-libraries/schema-index/index.d.ts +2 -2
  264. package/dist/feature-libraries/schema-index/index.d.ts.map +1 -1
  265. package/dist/feature-libraries/schema-index/index.js +2 -5
  266. package/dist/feature-libraries/schema-index/index.js.map +1 -1
  267. package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts +1 -9
  268. package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
  269. package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -12
  270. package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  271. package/dist/feature-libraries/schemaChecker.d.ts.map +1 -1
  272. package/dist/feature-libraries/schemaChecker.js +11 -6
  273. package/dist/feature-libraries/schemaChecker.js.map +1 -1
  274. package/dist/feature-libraries/sequence-field/compose.d.ts +6 -7
  275. package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
  276. package/dist/feature-libraries/sequence-field/compose.js +91 -263
  277. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  278. package/dist/feature-libraries/sequence-field/helperTypes.d.ts +14 -10
  279. package/dist/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
  280. package/dist/feature-libraries/sequence-field/helperTypes.js.map +1 -1
  281. package/dist/feature-libraries/sequence-field/index.d.ts +2 -3
  282. package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
  283. package/dist/feature-libraries/sequence-field/index.js +1 -3
  284. package/dist/feature-libraries/sequence-field/index.js.map +1 -1
  285. package/dist/feature-libraries/sequence-field/invert.d.ts +3 -3
  286. package/dist/feature-libraries/sequence-field/invert.d.ts.map +1 -1
  287. package/dist/feature-libraries/sequence-field/invert.js +67 -168
  288. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  289. package/dist/feature-libraries/sequence-field/markQueue.d.ts +2 -2
  290. package/dist/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
  291. package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
  292. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +4 -56
  293. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  294. package/dist/feature-libraries/sequence-field/moveEffectTable.js +10 -87
  295. package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  296. package/dist/feature-libraries/sequence-field/rebase.d.ts +3 -3
  297. package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  298. package/dist/feature-libraries/sequence-field/rebase.js +120 -119
  299. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  300. package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts +2 -2
  301. package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
  302. package/dist/feature-libraries/sequence-field/replaceRevisions.js +35 -43
  303. package/dist/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
  304. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  305. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +0 -2
  306. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  307. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +22 -4
  308. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
  309. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +365 -179
  310. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  311. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
  312. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js +20 -60
  313. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
  314. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
  315. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
  316. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
  317. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
  318. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +3 -2
  319. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  320. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +20 -112
  321. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  322. package/dist/feature-libraries/sequence-field/types.d.ts +30 -59
  323. package/dist/feature-libraries/sequence-field/types.d.ts.map +1 -1
  324. package/dist/feature-libraries/sequence-field/types.js.map +1 -1
  325. package/dist/feature-libraries/sequence-field/utils.d.ts +15 -24
  326. package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  327. package/dist/feature-libraries/sequence-field/utils.js +148 -318
  328. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  329. package/dist/feature-libraries/treeCursorUtils.js +7 -7
  330. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  331. package/dist/feature-libraries/treeTextCursor.js +2 -2
  332. package/dist/feature-libraries/treeTextCursor.js.map +1 -1
  333. package/dist/feature-libraries/valueUtilities.d.ts.map +1 -1
  334. package/dist/feature-libraries/valueUtilities.js +16 -8
  335. package/dist/feature-libraries/valueUtilities.js.map +1 -1
  336. package/dist/index.d.ts +4 -3
  337. package/dist/index.d.ts.map +1 -1
  338. package/dist/index.js +4 -1
  339. package/dist/index.js.map +1 -1
  340. package/dist/packageVersion.d.ts +1 -1
  341. package/dist/packageVersion.d.ts.map +1 -1
  342. package/dist/packageVersion.js +1 -1
  343. package/dist/packageVersion.js.map +1 -1
  344. package/dist/shared-tree/index.d.ts +1 -1
  345. package/dist/shared-tree/index.d.ts.map +1 -1
  346. package/dist/shared-tree/index.js.map +1 -1
  347. package/dist/shared-tree/schematizeTree.d.ts +4 -4
  348. package/dist/shared-tree/schematizeTree.d.ts.map +1 -1
  349. package/dist/shared-tree/schematizeTree.js +2 -1
  350. package/dist/shared-tree/schematizeTree.js.map +1 -1
  351. package/dist/shared-tree/schematizingTreeView.d.ts +3 -8
  352. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  353. package/dist/shared-tree/schematizingTreeView.js +58 -44
  354. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  355. package/dist/shared-tree/sharedTree.d.ts +9 -3
  356. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  357. package/dist/shared-tree/sharedTree.js +72 -44
  358. package/dist/shared-tree/sharedTree.js.map +1 -1
  359. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
  360. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  361. package/dist/shared-tree/sharedTreeChangeCodecs.js +10 -8
  362. package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  363. package/dist/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
  364. package/dist/shared-tree/sharedTreeChangeEnricher.js +5 -3
  365. package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  366. package/dist/shared-tree/sharedTreeChangeFamily.d.ts +7 -6
  367. package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  368. package/dist/shared-tree/sharedTreeChangeFamily.js +29 -18
  369. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  370. package/dist/shared-tree/sharedTreeEditBuilder.d.ts +16 -6
  371. package/dist/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
  372. package/dist/shared-tree/sharedTreeEditBuilder.js +14 -7
  373. package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  374. package/dist/shared-tree/treeAlpha.d.ts +35 -29
  375. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  376. package/dist/shared-tree/treeAlpha.js +21 -23
  377. package/dist/shared-tree/treeAlpha.js.map +1 -1
  378. package/dist/shared-tree/treeCheckout.d.ts +11 -10
  379. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  380. package/dist/shared-tree/treeCheckout.js +93 -25
  381. package/dist/shared-tree/treeCheckout.js.map +1 -1
  382. package/dist/shared-tree-core/branch.d.ts +6 -3
  383. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  384. package/dist/shared-tree-core/branch.js +13 -6
  385. package/dist/shared-tree-core/branch.js.map +1 -1
  386. package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  387. package/dist/shared-tree-core/branchCommitEnricher.js +1 -1
  388. package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
  389. package/dist/shared-tree-core/editManager.d.ts +2 -2
  390. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  391. package/dist/shared-tree-core/editManager.js +21 -15
  392. package/dist/shared-tree-core/editManager.js.map +1 -1
  393. package/dist/shared-tree-core/editManagerCodecs.d.ts +4 -0
  394. package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  395. package/dist/shared-tree-core/editManagerCodecs.js +18 -5
  396. package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
  397. package/dist/shared-tree-core/editManagerFormatCommons.d.ts +2 -0
  398. package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
  399. package/dist/shared-tree-core/editManagerFormatCommons.js +12 -0
  400. package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  401. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
  402. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
  403. package/dist/shared-tree-core/editManagerFormatV1toV4.js +2 -0
  404. package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  405. package/dist/shared-tree-core/editManagerSummarizer.js +3 -3
  406. package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
  407. package/dist/shared-tree-core/index.d.ts +2 -2
  408. package/dist/shared-tree-core/index.d.ts.map +1 -1
  409. package/dist/shared-tree-core/index.js +3 -1
  410. package/dist/shared-tree-core/index.js.map +1 -1
  411. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts +1 -1
  412. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  413. package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  414. package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  415. package/dist/shared-tree-core/messageCodecVSharedBranches.js +2 -1
  416. package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  417. package/dist/shared-tree-core/messageCodecs.d.ts +4 -0
  418. package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
  419. package/dist/shared-tree-core/messageCodecs.js +17 -5
  420. package/dist/shared-tree-core/messageCodecs.js.map +1 -1
  421. package/dist/shared-tree-core/messageFormat.d.ts +2 -0
  422. package/dist/shared-tree-core/messageFormat.d.ts.map +1 -1
  423. package/dist/shared-tree-core/messageFormat.js +12 -0
  424. package/dist/shared-tree-core/messageFormat.js.map +1 -1
  425. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +3 -2
  426. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
  427. package/dist/shared-tree-core/messageFormatV1ToV4.js +9 -1
  428. package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  429. package/dist/shared-tree-core/sequenceIdUtils.d.ts.map +1 -1
  430. package/dist/shared-tree-core/sequenceIdUtils.js +4 -4
  431. package/dist/shared-tree-core/sequenceIdUtils.js.map +1 -1
  432. package/dist/shared-tree-core/sharedTreeCore.d.ts +1 -0
  433. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  434. package/dist/shared-tree-core/sharedTreeCore.js +13 -9
  435. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  436. package/dist/shared-tree-core/transaction.d.ts +25 -8
  437. package/dist/shared-tree-core/transaction.d.ts.map +1 -1
  438. package/dist/shared-tree-core/transaction.js +65 -30
  439. package/dist/shared-tree-core/transaction.js.map +1 -1
  440. package/dist/shared-tree-core/transactionEnricher.d.ts +2 -2
  441. package/dist/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  442. package/dist/shared-tree-core/transactionEnricher.js +3 -3
  443. package/dist/shared-tree-core/transactionEnricher.js.map +1 -1
  444. package/dist/simple-tree/api/configuration.js +1 -1
  445. package/dist/simple-tree/api/configuration.js.map +1 -1
  446. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  447. package/dist/simple-tree/api/customTree.js +13 -9
  448. package/dist/simple-tree/api/customTree.js.map +1 -1
  449. package/dist/simple-tree/api/discrepancies.d.ts.map +1 -1
  450. package/dist/simple-tree/api/discrepancies.js +21 -17
  451. package/dist/simple-tree/api/discrepancies.js.map +1 -1
  452. package/dist/simple-tree/api/index.d.ts +2 -2
  453. package/dist/simple-tree/api/index.d.ts.map +1 -1
  454. package/dist/simple-tree/api/index.js +2 -1
  455. package/dist/simple-tree/api/index.js.map +1 -1
  456. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  457. package/dist/simple-tree/api/schemaFactory.js +12 -8
  458. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  459. package/dist/simple-tree/api/schemaFactoryAlpha.js +1 -1
  460. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  461. package/dist/simple-tree/api/schemaFactoryBeta.js +1 -1
  462. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  463. package/dist/simple-tree/api/schemaFromSimple.js +18 -9
  464. package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
  465. package/dist/simple-tree/api/simpleSchemaCodec.js +10 -5
  466. package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
  467. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  468. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +19 -15
  469. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  470. package/dist/simple-tree/api/simpleTreeIndex.js +10 -10
  471. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  472. package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts +244 -0
  473. package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
  474. package/dist/simple-tree/api/snapshotCompatibilityChecker.js +297 -1
  475. package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  476. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  477. package/dist/simple-tree/api/storedSchema.js +2 -3
  478. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  479. package/dist/simple-tree/api/transactionTypes.d.ts +17 -4
  480. package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
  481. package/dist/simple-tree/api/transactionTypes.js.map +1 -1
  482. package/dist/simple-tree/api/tree.d.ts +3 -1
  483. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  484. package/dist/simple-tree/api/tree.js.map +1 -1
  485. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  486. package/dist/simple-tree/api/treeNodeApi.js +21 -13
  487. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  488. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  489. package/dist/simple-tree/api/verboseTree.js +14 -9
  490. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  491. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  492. package/dist/simple-tree/core/treeNodeKernel.js +12 -5
  493. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  494. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +15 -15
  495. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  496. package/dist/simple-tree/core/unhydratedFlexTree.js +79 -23
  497. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  498. package/dist/simple-tree/fieldSchema.d.ts +4 -4
  499. package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
  500. package/dist/simple-tree/fieldSchema.js.map +1 -1
  501. package/dist/simple-tree/getTreeNodeForField.d.ts.map +1 -1
  502. package/dist/simple-tree/getTreeNodeForField.js +2 -1
  503. package/dist/simple-tree/getTreeNodeForField.js.map +1 -1
  504. package/dist/simple-tree/index.d.ts +3 -3
  505. package/dist/simple-tree/index.d.ts.map +1 -1
  506. package/dist/simple-tree/index.js +4 -3
  507. package/dist/simple-tree/index.js.map +1 -1
  508. package/dist/simple-tree/leafNodeSchema.js +9 -6
  509. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  510. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  511. package/dist/simple-tree/node-kinds/array/arrayNode.js +22 -20
  512. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  513. package/dist/simple-tree/node-kinds/common.d.ts.map +1 -1
  514. package/dist/simple-tree/node-kinds/common.js +1 -1
  515. package/dist/simple-tree/node-kinds/common.js.map +1 -1
  516. package/dist/simple-tree/node-kinds/map/mapNode.js +2 -2
  517. package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  518. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  519. package/dist/simple-tree/node-kinds/object/objectNode.js +21 -22
  520. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  521. package/dist/simple-tree/node-kinds/record/recordNode.js +6 -5
  522. package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  523. package/dist/simple-tree/prepareForInsertion.d.ts +54 -47
  524. package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
  525. package/dist/simple-tree/prepareForInsertion.js +184 -126
  526. package/dist/simple-tree/prepareForInsertion.js.map +1 -1
  527. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  528. package/dist/simple-tree/toStoredSchema.js +9 -5
  529. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  530. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +13 -4
  531. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  532. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +31 -13
  533. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  534. package/dist/text/index.d.ts +6 -0
  535. package/dist/text/index.d.ts.map +1 -0
  536. package/dist/text/index.js +10 -0
  537. package/dist/text/index.js.map +1 -0
  538. package/dist/text/textDomain.d.ts +138 -0
  539. package/dist/text/textDomain.d.ts.map +1 -0
  540. package/dist/text/textDomain.js +121 -0
  541. package/dist/text/textDomain.js.map +1 -0
  542. package/dist/treeFactory.d.ts.map +1 -1
  543. package/dist/treeFactory.js +17 -3
  544. package/dist/treeFactory.js.map +1 -1
  545. package/dist/util/bTreeUtils.d.ts +12 -4
  546. package/dist/util/bTreeUtils.d.ts.map +1 -1
  547. package/dist/util/bTreeUtils.js +15 -19
  548. package/dist/util/bTreeUtils.js.map +1 -1
  549. package/dist/util/breakable.js +7 -9
  550. package/dist/util/breakable.js.map +1 -1
  551. package/dist/util/idAllocator.d.ts.map +1 -1
  552. package/dist/util/idAllocator.js +1 -2
  553. package/dist/util/idAllocator.js.map +1 -1
  554. package/dist/util/index.d.ts +1 -1
  555. package/dist/util/index.d.ts.map +1 -1
  556. package/dist/util/index.js +2 -1
  557. package/dist/util/index.js.map +1 -1
  558. package/dist/util/nestedMap.d.ts.map +1 -1
  559. package/dist/util/nestedMap.js +13 -13
  560. package/dist/util/nestedMap.js.map +1 -1
  561. package/dist/util/rangeMap.d.ts +24 -12
  562. package/dist/util/rangeMap.d.ts.map +1 -1
  563. package/dist/util/rangeMap.js +46 -6
  564. package/dist/util/rangeMap.js.map +1 -1
  565. package/dist/util/utils.d.ts.map +1 -1
  566. package/dist/util/utils.js +16 -15
  567. package/dist/util/utils.js.map +1 -1
  568. package/docs/user-facing/merge-semantics.md +3 -2
  569. package/eslint.config.mts +5 -48
  570. package/lib/alpha.d.ts +9 -0
  571. package/lib/codec/codec.d.ts +31 -3
  572. package/lib/codec/codec.d.ts.map +1 -1
  573. package/lib/codec/codec.js +10 -0
  574. package/lib/codec/codec.js.map +1 -1
  575. package/lib/codec/index.d.ts +2 -2
  576. package/lib/codec/index.d.ts.map +1 -1
  577. package/lib/codec/index.js +1 -1
  578. package/lib/codec/index.js.map +1 -1
  579. package/lib/codec/versioned/codec.d.ts +80 -22
  580. package/lib/codec/versioned/codec.d.ts.map +1 -1
  581. package/lib/codec/versioned/codec.js +138 -15
  582. package/lib/codec/versioned/codec.js.map +1 -1
  583. package/lib/codec/versioned/index.d.ts +1 -1
  584. package/lib/codec/versioned/index.d.ts.map +1 -1
  585. package/lib/codec/versioned/index.js +1 -1
  586. package/lib/codec/versioned/index.js.map +1 -1
  587. package/lib/core/change-family/changeFamily.d.ts +4 -1
  588. package/lib/core/change-family/changeFamily.d.ts.map +1 -1
  589. package/lib/core/change-family/changeFamily.js.map +1 -1
  590. package/lib/core/change-family/index.d.ts +1 -1
  591. package/lib/core/change-family/index.d.ts.map +1 -1
  592. package/lib/core/change-family/index.js.map +1 -1
  593. package/lib/core/index.d.ts +3 -3
  594. package/lib/core/index.d.ts.map +1 -1
  595. package/lib/core/index.js +2 -2
  596. package/lib/core/index.js.map +1 -1
  597. package/lib/core/rebase/changeRebaser.d.ts +42 -3
  598. package/lib/core/rebase/changeRebaser.d.ts.map +1 -1
  599. package/lib/core/rebase/changeRebaser.js.map +1 -1
  600. package/lib/core/rebase/index.d.ts +2 -2
  601. package/lib/core/rebase/index.d.ts.map +1 -1
  602. package/lib/core/rebase/index.js +1 -1
  603. package/lib/core/rebase/index.js.map +1 -1
  604. package/lib/core/rebase/types.d.ts +52 -10
  605. package/lib/core/rebase/types.d.ts.map +1 -1
  606. package/lib/core/rebase/types.js +3 -10
  607. package/lib/core/rebase/types.js.map +1 -1
  608. package/lib/core/rebase/utils.d.ts.map +1 -1
  609. package/lib/core/rebase/utils.js +33 -11
  610. package/lib/core/rebase/utils.js.map +1 -1
  611. package/lib/core/schema-stored/schema.js +3 -3
  612. package/lib/core/schema-stored/schema.js.map +1 -1
  613. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  614. package/lib/core/tree/anchorSet.js +4 -4
  615. package/lib/core/tree/anchorSet.js.map +1 -1
  616. package/lib/core/tree/detachedFieldIndex.d.ts +7 -2
  617. package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
  618. package/lib/core/tree/detachedFieldIndex.js +23 -58
  619. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  620. package/lib/core/tree/detachedFieldIndexCodecCommon.d.ts +18 -10
  621. package/lib/core/tree/detachedFieldIndexCodecCommon.d.ts.map +1 -1
  622. package/lib/core/tree/detachedFieldIndexCodecCommon.js +4 -4
  623. package/lib/core/tree/detachedFieldIndexCodecCommon.js.map +1 -1
  624. package/lib/core/tree/detachedFieldIndexCodecV1.d.ts +2 -3
  625. package/lib/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
  626. package/lib/core/tree/detachedFieldIndexCodecV1.js +4 -5
  627. package/lib/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
  628. package/lib/core/tree/detachedFieldIndexCodecV2.d.ts +2 -3
  629. package/lib/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
  630. package/lib/core/tree/detachedFieldIndexCodecV2.js +4 -6
  631. package/lib/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
  632. package/lib/core/tree/detachedFieldIndexCodecs.d.ts +5 -6
  633. package/lib/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
  634. package/lib/core/tree/detachedFieldIndexCodecs.js +12 -39
  635. package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
  636. package/lib/core/tree/index.d.ts +2 -2
  637. package/lib/core/tree/index.d.ts.map +1 -1
  638. package/lib/core/tree/index.js +2 -2
  639. package/lib/core/tree/index.js.map +1 -1
  640. package/lib/core/tree/mapTree.js +1 -1
  641. package/lib/core/tree/mapTree.js.map +1 -1
  642. package/lib/core/tree/pathTree.d.ts +11 -3
  643. package/lib/core/tree/pathTree.d.ts.map +1 -1
  644. package/lib/core/tree/pathTree.js +12 -1
  645. package/lib/core/tree/pathTree.js.map +1 -1
  646. package/lib/core/tree/sparseTree.d.ts.map +1 -1
  647. package/lib/core/tree/sparseTree.js +1 -0
  648. package/lib/core/tree/sparseTree.js.map +1 -1
  649. package/lib/core/tree/treeTextFormat.d.ts.map +1 -1
  650. package/lib/core/tree/treeTextFormat.js +5 -9
  651. package/lib/core/tree/treeTextFormat.js.map +1 -1
  652. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  653. package/lib/core/tree/visitDelta.js +3 -2
  654. package/lib/core/tree/visitDelta.js.map +1 -1
  655. package/lib/core/tree/visitorUtils.d.ts.map +1 -1
  656. package/lib/core/tree/visitorUtils.js +58 -18
  657. package/lib/core/tree/visitorUtils.js.map +1 -1
  658. package/lib/feature-libraries/changeAtomIdBTree.d.ts +16 -0
  659. package/lib/feature-libraries/changeAtomIdBTree.d.ts.map +1 -0
  660. package/lib/feature-libraries/changeAtomIdBTree.js +24 -0
  661. package/lib/feature-libraries/changeAtomIdBTree.js.map +1 -0
  662. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  663. package/lib/feature-libraries/chunked-forest/basicChunk.js +9 -2
  664. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  665. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  666. package/lib/feature-libraries/chunked-forest/chunkTree.js +4 -1
  667. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  668. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  669. package/lib/feature-libraries/chunked-forest/chunkedForest.js +9 -7
  670. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  671. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  672. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +7 -4
  673. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  674. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  675. package/lib/feature-libraries/chunked-forest/codec/codecs.js +19 -11
  676. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  677. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
  678. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  679. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +9 -5
  680. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  681. package/lib/feature-libraries/chunked-forest/uniformChunk.js +1 -1
  682. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  683. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +103 -44
  684. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  685. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +249 -78
  686. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  687. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -1
  688. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  689. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +22 -3
  690. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  691. package/lib/feature-libraries/default-schema/index.d.ts +2 -1
  692. package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
  693. package/lib/feature-libraries/default-schema/index.js +2 -1
  694. package/lib/feature-libraries/default-schema/index.js.map +1 -1
  695. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +38 -0
  696. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +1 -0
  697. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js +128 -0
  698. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js.map +1 -0
  699. package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts +9 -6
  700. package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
  701. package/lib/feature-libraries/default-schema/mappedEditBuilder.js +21 -0
  702. package/lib/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
  703. package/lib/feature-libraries/deltaUtils.d.ts +1 -0
  704. package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
  705. package/lib/feature-libraries/deltaUtils.js +5 -1
  706. package/lib/feature-libraries/deltaUtils.js.map +1 -1
  707. package/lib/feature-libraries/flex-tree/context.d.ts +9 -0
  708. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  709. package/lib/feature-libraries/flex-tree/context.js +6 -0
  710. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  711. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
  712. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  713. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  714. package/lib/feature-libraries/flex-tree/lazyField.d.ts +8 -7
  715. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  716. package/lib/feature-libraries/flex-tree/lazyField.js +45 -16
  717. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  718. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  719. package/lib/feature-libraries/forest-summary/forestSummarizer.js +3 -1
  720. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  721. package/lib/feature-libraries/index.d.ts +5 -4
  722. package/lib/feature-libraries/index.d.ts.map +1 -1
  723. package/lib/feature-libraries/index.js +5 -4
  724. package/lib/feature-libraries/index.js.map +1 -1
  725. package/lib/feature-libraries/indexing/anchorTreeIndex.js +6 -6
  726. package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
  727. package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
  728. package/lib/feature-libraries/mapTreeCursor.js +2 -1
  729. package/lib/feature-libraries/mapTreeCursor.js.map +1 -1
  730. package/lib/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
  731. package/lib/feature-libraries/mitigatedChangeFamily.js +12 -3
  732. package/lib/feature-libraries/mitigatedChangeFamily.js.map +1 -1
  733. package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
  734. package/lib/feature-libraries/modular-schema/comparison.js +12 -9
  735. package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
  736. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +97 -21
  737. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  738. package/lib/feature-libraries/modular-schema/crossFieldQueries.js +3 -5
  739. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  740. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +25 -0
  741. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -0
  742. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js +55 -0
  743. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -0
  744. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +22 -53
  745. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  746. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  747. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  748. package/lib/feature-libraries/modular-schema/genericFieldKind.js +8 -14
  749. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  750. package/lib/feature-libraries/modular-schema/genericFieldKindCodecs.js +1 -1
  751. package/lib/feature-libraries/modular-schema/genericFieldKindCodecs.js.map +1 -1
  752. package/lib/feature-libraries/modular-schema/index.d.ts +7 -5
  753. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  754. package/lib/feature-libraries/modular-schema/index.js +5 -3
  755. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  756. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +32 -0
  757. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -0
  758. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +402 -0
  759. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -0
  760. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +15 -0
  761. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -0
  762. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js +27 -0
  763. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -0
  764. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.d.ts +15 -0
  765. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.d.ts.map +1 -0
  766. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.js +389 -0
  767. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.js.map +1 -0
  768. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
  769. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  770. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +34 -290
  771. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  772. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +60 -26
  773. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  774. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1441 -546
  775. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  776. package/{dist/feature-libraries/modular-schema/modularChangeFormat.d.ts → lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts} +5 -6
  777. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -0
  778. package/lib/feature-libraries/modular-schema/{modularChangeFormat.js → modularChangeFormatV1.js} +4 -4
  779. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -0
  780. package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +112 -0
  781. package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -0
  782. package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js +18 -0
  783. package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -0
  784. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.d.ts +146 -0
  785. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.d.ts.map +1 -0
  786. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.js +29 -0
  787. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.js.map +1 -0
  788. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +59 -13
  789. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  790. package/lib/feature-libraries/modular-schema/modularChangeTypes.js +1 -1
  791. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  792. package/lib/feature-libraries/node-identifier/mockNodeIdentifierManager.js +1 -1
  793. package/lib/feature-libraries/node-identifier/mockNodeIdentifierManager.js.map +1 -1
  794. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  795. package/lib/feature-libraries/object-forest/objectForest.js +7 -5
  796. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  797. package/lib/feature-libraries/optional-field/index.d.ts +2 -2
  798. package/lib/feature-libraries/optional-field/index.d.ts.map +1 -1
  799. package/lib/feature-libraries/optional-field/index.js +1 -1
  800. package/lib/feature-libraries/optional-field/index.js.map +1 -1
  801. package/lib/feature-libraries/optional-field/optionalField.d.ts +5 -26
  802. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  803. package/lib/feature-libraries/optional-field/optionalField.js +223 -448
  804. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  805. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +23 -0
  806. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +1 -0
  807. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +27 -0
  808. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +1 -0
  809. package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +24 -33
  810. package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
  811. package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
  812. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
  813. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
  814. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js +55 -26
  815. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
  816. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +12 -0
  817. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +1 -0
  818. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js +53 -0
  819. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js.map +1 -0
  820. package/lib/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
  821. package/lib/feature-libraries/optional-field/optionalFieldCodecs.js +5 -1
  822. package/lib/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
  823. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
  824. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js +15 -3
  825. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
  826. package/lib/feature-libraries/schema-index/codec.d.ts +7 -21
  827. package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
  828. package/lib/feature-libraries/schema-index/codec.js +30 -68
  829. package/lib/feature-libraries/schema-index/codec.js.map +1 -1
  830. package/lib/feature-libraries/schema-index/index.d.ts +2 -2
  831. package/lib/feature-libraries/schema-index/index.d.ts.map +1 -1
  832. package/lib/feature-libraries/schema-index/index.js +2 -2
  833. package/lib/feature-libraries/schema-index/index.js.map +1 -1
  834. package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts +1 -9
  835. package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
  836. package/lib/feature-libraries/schema-index/schemaSummarizer.js +0 -10
  837. package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  838. package/lib/feature-libraries/schemaChecker.d.ts.map +1 -1
  839. package/lib/feature-libraries/schemaChecker.js +11 -6
  840. package/lib/feature-libraries/schemaChecker.js.map +1 -1
  841. package/lib/feature-libraries/sequence-field/compose.d.ts +6 -7
  842. package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
  843. package/lib/feature-libraries/sequence-field/compose.js +93 -265
  844. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  845. package/lib/feature-libraries/sequence-field/helperTypes.d.ts +14 -10
  846. package/lib/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
  847. package/lib/feature-libraries/sequence-field/helperTypes.js.map +1 -1
  848. package/lib/feature-libraries/sequence-field/index.d.ts +2 -3
  849. package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
  850. package/lib/feature-libraries/sequence-field/index.js +0 -1
  851. package/lib/feature-libraries/sequence-field/index.js.map +1 -1
  852. package/lib/feature-libraries/sequence-field/invert.d.ts +3 -3
  853. package/lib/feature-libraries/sequence-field/invert.d.ts.map +1 -1
  854. package/lib/feature-libraries/sequence-field/invert.js +69 -170
  855. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  856. package/lib/feature-libraries/sequence-field/markQueue.d.ts +2 -2
  857. package/lib/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
  858. package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
  859. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +4 -56
  860. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  861. package/lib/feature-libraries/sequence-field/moveEffectTable.js +9 -81
  862. package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  863. package/lib/feature-libraries/sequence-field/rebase.d.ts +3 -3
  864. package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  865. package/lib/feature-libraries/sequence-field/rebase.js +122 -121
  866. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  867. package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts +2 -2
  868. package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
  869. package/lib/feature-libraries/sequence-field/replaceRevisions.js +36 -44
  870. package/lib/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
  871. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  872. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +0 -2
  873. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  874. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +22 -4
  875. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
  876. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +356 -174
  877. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  878. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
  879. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js +21 -61
  880. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
  881. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
  882. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
  883. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
  884. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
  885. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +3 -2
  886. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  887. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +20 -112
  888. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  889. package/lib/feature-libraries/sequence-field/types.d.ts +30 -59
  890. package/lib/feature-libraries/sequence-field/types.d.ts.map +1 -1
  891. package/lib/feature-libraries/sequence-field/types.js.map +1 -1
  892. package/lib/feature-libraries/sequence-field/utils.d.ts +15 -24
  893. package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  894. package/lib/feature-libraries/sequence-field/utils.js +144 -311
  895. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  896. package/lib/feature-libraries/treeCursorUtils.js +7 -7
  897. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  898. package/lib/feature-libraries/treeTextCursor.js +2 -2
  899. package/lib/feature-libraries/treeTextCursor.js.map +1 -1
  900. package/lib/feature-libraries/valueUtilities.d.ts.map +1 -1
  901. package/lib/feature-libraries/valueUtilities.js +16 -8
  902. package/lib/feature-libraries/valueUtilities.js.map +1 -1
  903. package/lib/index.d.ts +4 -3
  904. package/lib/index.d.ts.map +1 -1
  905. package/lib/index.js +2 -1
  906. package/lib/index.js.map +1 -1
  907. package/lib/packageVersion.d.ts +1 -1
  908. package/lib/packageVersion.d.ts.map +1 -1
  909. package/lib/packageVersion.js +1 -1
  910. package/lib/packageVersion.js.map +1 -1
  911. package/lib/shared-tree/index.d.ts +1 -1
  912. package/lib/shared-tree/index.d.ts.map +1 -1
  913. package/lib/shared-tree/index.js.map +1 -1
  914. package/lib/shared-tree/schematizeTree.d.ts +4 -4
  915. package/lib/shared-tree/schematizeTree.d.ts.map +1 -1
  916. package/lib/shared-tree/schematizeTree.js +3 -2
  917. package/lib/shared-tree/schematizeTree.js.map +1 -1
  918. package/lib/shared-tree/schematizingTreeView.d.ts +3 -8
  919. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  920. package/lib/shared-tree/schematizingTreeView.js +61 -47
  921. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  922. package/lib/shared-tree/sharedTree.d.ts +9 -3
  923. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  924. package/lib/shared-tree/sharedTree.js +41 -13
  925. package/lib/shared-tree/sharedTree.js.map +1 -1
  926. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
  927. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  928. package/lib/shared-tree/sharedTreeChangeCodecs.js +10 -8
  929. package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  930. package/lib/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
  931. package/lib/shared-tree/sharedTreeChangeEnricher.js +6 -4
  932. package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  933. package/lib/shared-tree/sharedTreeChangeFamily.d.ts +7 -6
  934. package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  935. package/lib/shared-tree/sharedTreeChangeFamily.js +30 -19
  936. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  937. package/lib/shared-tree/sharedTreeEditBuilder.d.ts +16 -6
  938. package/lib/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
  939. package/lib/shared-tree/sharedTreeEditBuilder.js +12 -6
  940. package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  941. package/lib/shared-tree/treeAlpha.d.ts +35 -29
  942. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  943. package/lib/shared-tree/treeAlpha.js +21 -23
  944. package/lib/shared-tree/treeAlpha.js.map +1 -1
  945. package/lib/shared-tree/treeCheckout.d.ts +11 -10
  946. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  947. package/lib/shared-tree/treeCheckout.js +97 -29
  948. package/lib/shared-tree/treeCheckout.js.map +1 -1
  949. package/lib/shared-tree-core/branch.d.ts +6 -3
  950. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  951. package/lib/shared-tree-core/branch.js +13 -6
  952. package/lib/shared-tree-core/branch.js.map +1 -1
  953. package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  954. package/lib/shared-tree-core/branchCommitEnricher.js +2 -2
  955. package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
  956. package/lib/shared-tree-core/editManager.d.ts +2 -2
  957. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  958. package/lib/shared-tree-core/editManager.js +21 -15
  959. package/lib/shared-tree-core/editManager.js.map +1 -1
  960. package/lib/shared-tree-core/editManagerCodecs.d.ts +4 -0
  961. package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  962. package/lib/shared-tree-core/editManagerCodecs.js +16 -4
  963. package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
  964. package/lib/shared-tree-core/editManagerFormatCommons.d.ts +2 -0
  965. package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
  966. package/lib/shared-tree-core/editManagerFormatCommons.js +12 -0
  967. package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  968. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
  969. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
  970. package/lib/shared-tree-core/editManagerFormatV1toV4.js +2 -0
  971. package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  972. package/lib/shared-tree-core/editManagerSummarizer.js +3 -3
  973. package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
  974. package/lib/shared-tree-core/index.d.ts +2 -2
  975. package/lib/shared-tree-core/index.d.ts.map +1 -1
  976. package/lib/shared-tree-core/index.js +2 -2
  977. package/lib/shared-tree-core/index.js.map +1 -1
  978. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts +1 -1
  979. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  980. package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  981. package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  982. package/lib/shared-tree-core/messageCodecVSharedBranches.js +2 -1
  983. package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  984. package/lib/shared-tree-core/messageCodecs.d.ts +4 -0
  985. package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
  986. package/lib/shared-tree-core/messageCodecs.js +15 -4
  987. package/lib/shared-tree-core/messageCodecs.js.map +1 -1
  988. package/lib/shared-tree-core/messageFormat.d.ts +2 -0
  989. package/lib/shared-tree-core/messageFormat.d.ts.map +1 -1
  990. package/lib/shared-tree-core/messageFormat.js +12 -0
  991. package/lib/shared-tree-core/messageFormat.js.map +1 -1
  992. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +3 -2
  993. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
  994. package/lib/shared-tree-core/messageFormatV1ToV4.js +9 -1
  995. package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  996. package/lib/shared-tree-core/sequenceIdUtils.d.ts.map +1 -1
  997. package/lib/shared-tree-core/sequenceIdUtils.js +4 -4
  998. package/lib/shared-tree-core/sequenceIdUtils.js.map +1 -1
  999. package/lib/shared-tree-core/sharedTreeCore.d.ts +1 -0
  1000. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  1001. package/lib/shared-tree-core/sharedTreeCore.js +13 -9
  1002. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  1003. package/lib/shared-tree-core/transaction.d.ts +25 -8
  1004. package/lib/shared-tree-core/transaction.d.ts.map +1 -1
  1005. package/lib/shared-tree-core/transaction.js +67 -32
  1006. package/lib/shared-tree-core/transaction.js.map +1 -1
  1007. package/lib/shared-tree-core/transactionEnricher.d.ts +2 -2
  1008. package/lib/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  1009. package/lib/shared-tree-core/transactionEnricher.js +3 -3
  1010. package/lib/shared-tree-core/transactionEnricher.js.map +1 -1
  1011. package/lib/simple-tree/api/configuration.js +1 -1
  1012. package/lib/simple-tree/api/configuration.js.map +1 -1
  1013. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  1014. package/lib/simple-tree/api/customTree.js +13 -9
  1015. package/lib/simple-tree/api/customTree.js.map +1 -1
  1016. package/lib/simple-tree/api/discrepancies.d.ts.map +1 -1
  1017. package/lib/simple-tree/api/discrepancies.js +21 -17
  1018. package/lib/simple-tree/api/discrepancies.js.map +1 -1
  1019. package/lib/simple-tree/api/index.d.ts +2 -2
  1020. package/lib/simple-tree/api/index.d.ts.map +1 -1
  1021. package/lib/simple-tree/api/index.js +1 -1
  1022. package/lib/simple-tree/api/index.js.map +1 -1
  1023. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  1024. package/lib/simple-tree/api/schemaFactory.js +12 -8
  1025. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  1026. package/lib/simple-tree/api/schemaFactoryAlpha.js +1 -1
  1027. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  1028. package/lib/simple-tree/api/schemaFactoryBeta.js +1 -1
  1029. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  1030. package/lib/simple-tree/api/schemaFromSimple.js +18 -9
  1031. package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
  1032. package/lib/simple-tree/api/simpleSchemaCodec.js +10 -5
  1033. package/lib/simple-tree/api/simpleSchemaCodec.js.map +1 -1
  1034. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  1035. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +19 -15
  1036. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  1037. package/lib/simple-tree/api/simpleTreeIndex.js +10 -10
  1038. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  1039. package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts +244 -0
  1040. package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
  1041. package/lib/simple-tree/api/snapshotCompatibilityChecker.js +270 -0
  1042. package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  1043. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  1044. package/lib/simple-tree/api/storedSchema.js +4 -7
  1045. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  1046. package/lib/simple-tree/api/transactionTypes.d.ts +17 -4
  1047. package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
  1048. package/lib/simple-tree/api/transactionTypes.js.map +1 -1
  1049. package/lib/simple-tree/api/tree.d.ts +3 -1
  1050. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  1051. package/lib/simple-tree/api/tree.js.map +1 -1
  1052. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  1053. package/lib/simple-tree/api/treeNodeApi.js +21 -13
  1054. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  1055. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  1056. package/lib/simple-tree/api/verboseTree.js +14 -9
  1057. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  1058. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  1059. package/lib/simple-tree/core/treeNodeKernel.js +12 -5
  1060. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  1061. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +15 -15
  1062. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  1063. package/lib/simple-tree/core/unhydratedFlexTree.js +78 -23
  1064. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  1065. package/lib/simple-tree/fieldSchema.d.ts +4 -4
  1066. package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
  1067. package/lib/simple-tree/fieldSchema.js.map +1 -1
  1068. package/lib/simple-tree/getTreeNodeForField.d.ts.map +1 -1
  1069. package/lib/simple-tree/getTreeNodeForField.js +2 -1
  1070. package/lib/simple-tree/getTreeNodeForField.js.map +1 -1
  1071. package/lib/simple-tree/index.d.ts +3 -3
  1072. package/lib/simple-tree/index.d.ts.map +1 -1
  1073. package/lib/simple-tree/index.js +2 -2
  1074. package/lib/simple-tree/index.js.map +1 -1
  1075. package/lib/simple-tree/leafNodeSchema.js +9 -6
  1076. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  1077. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  1078. package/lib/simple-tree/node-kinds/array/arrayNode.js +23 -21
  1079. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  1080. package/lib/simple-tree/node-kinds/common.d.ts.map +1 -1
  1081. package/lib/simple-tree/node-kinds/common.js +2 -2
  1082. package/lib/simple-tree/node-kinds/common.js.map +1 -1
  1083. package/lib/simple-tree/node-kinds/map/mapNode.js +2 -2
  1084. package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  1085. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  1086. package/lib/simple-tree/node-kinds/object/objectNode.js +22 -23
  1087. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  1088. package/lib/simple-tree/node-kinds/record/recordNode.js +6 -5
  1089. package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  1090. package/lib/simple-tree/prepareForInsertion.d.ts +54 -47
  1091. package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
  1092. package/lib/simple-tree/prepareForInsertion.js +184 -125
  1093. package/lib/simple-tree/prepareForInsertion.js.map +1 -1
  1094. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  1095. package/lib/simple-tree/toStoredSchema.js +9 -5
  1096. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  1097. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +13 -4
  1098. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  1099. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +28 -11
  1100. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  1101. package/lib/text/index.d.ts +6 -0
  1102. package/lib/text/index.d.ts.map +1 -0
  1103. package/lib/text/index.js +6 -0
  1104. package/lib/text/index.js.map +1 -0
  1105. package/lib/text/textDomain.d.ts +138 -0
  1106. package/lib/text/textDomain.d.ts.map +1 -0
  1107. package/lib/text/textDomain.js +118 -0
  1108. package/lib/text/textDomain.js.map +1 -0
  1109. package/lib/treeFactory.d.ts.map +1 -1
  1110. package/lib/treeFactory.js +18 -4
  1111. package/lib/treeFactory.js.map +1 -1
  1112. package/lib/util/bTreeUtils.d.ts +12 -4
  1113. package/lib/util/bTreeUtils.d.ts.map +1 -1
  1114. package/lib/util/bTreeUtils.js +16 -20
  1115. package/lib/util/bTreeUtils.js.map +1 -1
  1116. package/lib/util/breakable.js +7 -9
  1117. package/lib/util/breakable.js.map +1 -1
  1118. package/lib/util/idAllocator.d.ts.map +1 -1
  1119. package/lib/util/idAllocator.js +1 -2
  1120. package/lib/util/idAllocator.js.map +1 -1
  1121. package/lib/util/index.d.ts +1 -1
  1122. package/lib/util/index.d.ts.map +1 -1
  1123. package/lib/util/index.js +1 -1
  1124. package/lib/util/index.js.map +1 -1
  1125. package/lib/util/nestedMap.d.ts.map +1 -1
  1126. package/lib/util/nestedMap.js +13 -13
  1127. package/lib/util/nestedMap.js.map +1 -1
  1128. package/lib/util/rangeMap.d.ts +24 -12
  1129. package/lib/util/rangeMap.d.ts.map +1 -1
  1130. package/lib/util/rangeMap.js +44 -5
  1131. package/lib/util/rangeMap.js.map +1 -1
  1132. package/lib/util/utils.d.ts.map +1 -1
  1133. package/lib/util/utils.js +16 -15
  1134. package/lib/util/utils.js.map +1 -1
  1135. package/package.json +33 -33
  1136. package/src/codec/codec.ts +48 -8
  1137. package/src/codec/index.ts +4 -1
  1138. package/src/codec/versioned/codec.ts +340 -22
  1139. package/src/codec/versioned/index.ts +3 -1
  1140. package/src/core/change-family/changeFamily.ts +5 -0
  1141. package/src/core/change-family/index.ts +1 -0
  1142. package/src/core/index.ts +8 -3
  1143. package/src/core/rebase/changeRebaser.ts +46 -7
  1144. package/src/core/rebase/index.ts +4 -1
  1145. package/src/core/rebase/types.ts +71 -39
  1146. package/src/core/rebase/utils.ts +42 -14
  1147. package/src/core/schema-stored/schema.ts +3 -3
  1148. package/src/core/tree/anchorSet.ts +4 -4
  1149. package/src/core/tree/detachedFieldIndex.ts +29 -74
  1150. package/src/core/tree/detachedFieldIndexCodecCommon.ts +4 -8
  1151. package/src/core/tree/detachedFieldIndexCodecV1.ts +3 -7
  1152. package/src/core/tree/detachedFieldIndexCodecV2.ts +5 -9
  1153. package/src/core/tree/detachedFieldIndexCodecs.ts +21 -64
  1154. package/src/core/tree/index.ts +3 -2
  1155. package/src/core/tree/mapTree.ts +1 -1
  1156. package/src/core/tree/pathTree.ts +16 -4
  1157. package/src/core/tree/sparseTree.ts +1 -0
  1158. package/src/core/tree/treeTextFormat.ts +5 -9
  1159. package/src/core/tree/visitDelta.ts +6 -2
  1160. package/src/core/tree/visitorUtils.ts +55 -19
  1161. package/src/feature-libraries/changeAtomIdBTree.ts +56 -0
  1162. package/src/feature-libraries/chunked-forest/basicChunk.ts +8 -2
  1163. package/src/feature-libraries/chunked-forest/chunkTree.ts +6 -1
  1164. package/src/feature-libraries/chunked-forest/chunkedForest.ts +8 -6
  1165. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +7 -4
  1166. package/src/feature-libraries/chunked-forest/codec/codecs.ts +19 -11
  1167. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +4 -3
  1168. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +9 -5
  1169. package/src/feature-libraries/chunked-forest/uniformChunk.ts +1 -1
  1170. package/src/feature-libraries/default-schema/defaultEditBuilder.ts +442 -139
  1171. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +24 -6
  1172. package/src/feature-libraries/default-schema/index.ts +17 -5
  1173. package/src/feature-libraries/default-schema/locationBasedEditBuilder.ts +188 -0
  1174. package/src/feature-libraries/default-schema/mappedEditBuilder.ts +41 -9
  1175. package/src/feature-libraries/deltaUtils.ts +6 -1
  1176. package/src/feature-libraries/flex-tree/context.ts +17 -0
  1177. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +7 -8
  1178. package/src/feature-libraries/flex-tree/lazyField.ts +72 -30
  1179. package/src/feature-libraries/forest-summary/forestSummarizer.ts +3 -1
  1180. package/src/feature-libraries/index.ts +32 -13
  1181. package/src/feature-libraries/indexing/anchorTreeIndex.ts +5 -5
  1182. package/src/feature-libraries/mapTreeCursor.ts +2 -1
  1183. package/src/feature-libraries/mitigatedChangeFamily.ts +14 -7
  1184. package/src/feature-libraries/modular-schema/comparison.ts +12 -9
  1185. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +142 -44
  1186. package/src/feature-libraries/modular-schema/defaultRevisionReplacer.ts +70 -0
  1187. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +35 -64
  1188. package/src/feature-libraries/modular-schema/genericFieldKind.ts +11 -25
  1189. package/src/feature-libraries/modular-schema/genericFieldKindCodecs.ts +1 -1
  1190. package/src/feature-libraries/modular-schema/index.ts +20 -16
  1191. package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +912 -0
  1192. package/src/feature-libraries/modular-schema/modularChangeCodecV2.ts +89 -0
  1193. package/src/feature-libraries/modular-schema/modularChangeCodecV3.ts +760 -0
  1194. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +52 -523
  1195. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +2756 -884
  1196. package/src/feature-libraries/modular-schema/{modularChangeFormat.ts → modularChangeFormatV1.ts} +5 -4
  1197. package/src/feature-libraries/modular-schema/modularChangeFormatV2.ts +34 -0
  1198. package/src/feature-libraries/modular-schema/modularChangeFormatV3.ts +62 -0
  1199. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +70 -14
  1200. package/src/feature-libraries/node-identifier/mockNodeIdentifierManager.ts +1 -1
  1201. package/src/feature-libraries/object-forest/objectForest.ts +7 -5
  1202. package/src/feature-libraries/optional-field/index.ts +1 -3
  1203. package/src/feature-libraries/optional-field/optionalField.ts +320 -576
  1204. package/src/feature-libraries/optional-field/optionalFieldChangeFormatV3.ts +45 -0
  1205. package/src/feature-libraries/optional-field/optionalFieldChangeTypes.ts +24 -38
  1206. package/src/feature-libraries/optional-field/optionalFieldCodecV2.ts +89 -35
  1207. package/src/feature-libraries/optional-field/optionalFieldCodecV3.ts +94 -0
  1208. package/src/feature-libraries/optional-field/optionalFieldCodecs.ts +5 -1
  1209. package/src/feature-libraries/schema-edits/schemaChangeCodecs.ts +18 -3
  1210. package/src/feature-libraries/schema-index/codec.ts +30 -90
  1211. package/src/feature-libraries/schema-index/index.ts +2 -4
  1212. package/src/feature-libraries/schema-index/schemaSummarizer.ts +0 -17
  1213. package/src/feature-libraries/schemaChecker.ts +11 -6
  1214. package/src/feature-libraries/sequence-field/compose.ts +147 -526
  1215. package/src/feature-libraries/sequence-field/helperTypes.ts +34 -19
  1216. package/src/feature-libraries/sequence-field/index.ts +0 -9
  1217. package/src/feature-libraries/sequence-field/invert.ts +103 -227
  1218. package/src/feature-libraries/sequence-field/markQueue.ts +2 -2
  1219. package/src/feature-libraries/sequence-field/moveEffectTable.ts +11 -192
  1220. package/src/feature-libraries/sequence-field/rebase.ts +182 -210
  1221. package/src/feature-libraries/sequence-field/replaceRevisions.ts +54 -80
  1222. package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +0 -2
  1223. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +648 -220
  1224. package/src/feature-libraries/sequence-field/sequenceFieldCodecV3.ts +56 -68
  1225. package/src/feature-libraries/sequence-field/sequenceFieldEditor.ts +25 -27
  1226. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +25 -132
  1227. package/src/feature-libraries/sequence-field/types.ts +34 -64
  1228. package/src/feature-libraries/sequence-field/utils.ts +171 -366
  1229. package/src/feature-libraries/treeCursorUtils.ts +7 -7
  1230. package/src/feature-libraries/treeTextCursor.ts +2 -2
  1231. package/src/feature-libraries/valueUtilities.ts +16 -8
  1232. package/src/index.ts +11 -0
  1233. package/src/packageVersion.ts +1 -1
  1234. package/src/shared-tree/index.ts +3 -2
  1235. package/src/shared-tree/schematizeTree.ts +21 -8
  1236. package/src/shared-tree/schematizingTreeView.ts +79 -83
  1237. package/src/shared-tree/sharedTree.ts +50 -17
  1238. package/src/shared-tree/sharedTreeChangeCodecs.ts +14 -9
  1239. package/src/shared-tree/sharedTreeChangeEnricher.ts +6 -2
  1240. package/src/shared-tree/sharedTreeChangeFamily.ts +44 -24
  1241. package/src/shared-tree/sharedTreeEditBuilder.ts +48 -13
  1242. package/src/shared-tree/treeAlpha.ts +60 -51
  1243. package/src/shared-tree/treeCheckout.ts +160 -73
  1244. package/src/shared-tree-core/branch.ts +21 -6
  1245. package/src/shared-tree-core/branchCommitEnricher.ts +3 -8
  1246. package/src/shared-tree-core/editManager.ts +43 -29
  1247. package/src/shared-tree-core/editManagerCodecs.ts +19 -4
  1248. package/src/shared-tree-core/editManagerFormatCommons.ts +12 -0
  1249. package/src/shared-tree-core/editManagerFormatV1toV4.ts +5 -1
  1250. package/src/shared-tree-core/editManagerSummarizer.ts +3 -3
  1251. package/src/shared-tree-core/index.ts +2 -0
  1252. package/src/shared-tree-core/messageCodecV1ToV4.ts +3 -1
  1253. package/src/shared-tree-core/messageCodecVSharedBranches.ts +2 -1
  1254. package/src/shared-tree-core/messageCodecs.ts +18 -4
  1255. package/src/shared-tree-core/messageFormat.ts +12 -1
  1256. package/src/shared-tree-core/messageFormatV1ToV4.ts +18 -2
  1257. package/src/shared-tree-core/sequenceIdUtils.ts +4 -4
  1258. package/src/shared-tree-core/sharedTreeCore.ts +15 -8
  1259. package/src/shared-tree-core/transaction.ts +115 -56
  1260. package/src/shared-tree-core/transactionEnricher.ts +5 -6
  1261. package/src/simple-tree/api/configuration.ts +1 -1
  1262. package/src/simple-tree/api/customTree.ts +14 -10
  1263. package/src/simple-tree/api/discrepancies.ts +23 -17
  1264. package/src/simple-tree/api/index.ts +5 -0
  1265. package/src/simple-tree/api/schemaFactory.ts +11 -7
  1266. package/src/simple-tree/api/schemaFactoryAlpha.ts +1 -1
  1267. package/src/simple-tree/api/schemaFactoryBeta.ts +1 -1
  1268. package/src/simple-tree/api/schemaFromSimple.ts +18 -9
  1269. package/src/simple-tree/api/simpleSchemaCodec.ts +10 -5
  1270. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +21 -17
  1271. package/src/simple-tree/api/simpleTreeIndex.ts +8 -8
  1272. package/src/simple-tree/api/snapshotCompatibilityChecker.ts +501 -0
  1273. package/src/simple-tree/api/storedSchema.ts +10 -7
  1274. package/src/simple-tree/api/transactionTypes.ts +19 -4
  1275. package/src/simple-tree/api/tree.ts +3 -1
  1276. package/src/simple-tree/api/treeNodeApi.ts +21 -13
  1277. package/src/simple-tree/api/verboseTree.ts +14 -9
  1278. package/src/simple-tree/core/treeNodeKernel.ts +12 -5
  1279. package/src/simple-tree/core/unhydratedFlexTree.ts +109 -53
  1280. package/src/simple-tree/fieldSchema.ts +6 -4
  1281. package/src/simple-tree/getTreeNodeForField.ts +2 -1
  1282. package/src/simple-tree/index.ts +7 -1
  1283. package/src/simple-tree/leafNodeSchema.ts +8 -5
  1284. package/src/simple-tree/node-kinds/array/arrayNode.ts +32 -30
  1285. package/src/simple-tree/node-kinds/common.ts +2 -5
  1286. package/src/simple-tree/node-kinds/map/mapNode.ts +4 -4
  1287. package/src/simple-tree/node-kinds/object/objectNode.ts +29 -30
  1288. package/src/simple-tree/node-kinds/record/recordNode.ts +12 -12
  1289. package/src/simple-tree/prepareForInsertion.ts +343 -201
  1290. package/src/simple-tree/toStoredSchema.ts +9 -5
  1291. package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +43 -15
  1292. package/src/text/README.md +8 -0
  1293. package/src/text/index.ts +6 -0
  1294. package/src/text/textDomain.ts +199 -0
  1295. package/src/treeFactory.ts +20 -5
  1296. package/src/util/bTreeUtils.ts +34 -23
  1297. package/src/util/breakable.ts +9 -9
  1298. package/src/util/idAllocator.ts +1 -2
  1299. package/src/util/index.ts +3 -0
  1300. package/src/util/nestedMap.ts +13 -15
  1301. package/src/util/rangeMap.ts +72 -18
  1302. package/src/util/utils.ts +14 -13
  1303. package/.eslintrc.cjs +0 -140
  1304. package/assertTagging.config.mjs +0 -14
  1305. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +0 -1
  1306. package/dist/feature-libraries/modular-schema/modularChangeFormat.js.map +0 -1
  1307. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +0 -9
  1308. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +0 -1
  1309. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js +0 -50
  1310. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js.map +0 -1
  1311. package/docs/main/sequence-field/move-composition.md +0 -46
  1312. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +0 -1
  1313. package/lib/feature-libraries/modular-schema/modularChangeFormat.js.map +0 -1
  1314. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +0 -9
  1315. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +0 -1
  1316. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js +0 -46
  1317. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js.map +0 -1
  1318. package/src/feature-libraries/sequence-field/relevantRemovedRoots.ts +0 -57
@@ -4,22 +4,27 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.normalizeFieldId = exports.getParentFieldId = exports.ModularEditBuilder = exports.getChangeHandler = exports.getFieldKind = exports.rebaseRevisionMetadataFromInfo = exports.intoDelta = exports.updateRefreshers = exports.relevantRemovedRoots = exports.ModularChangeFamily = void 0;
7
+ exports.validateChangeset = exports.addNodeRename = exports.getFirstAttachField = exports.getFirstDetachField = exports.cloneRootTable = exports.newRootTable = exports.normalizeNodeId = exports.normalizeFieldId = exports.getNodeParent = exports.buildModularChangesetFromField = exports.ModularEditBuilder = exports.getChangeHandler = exports.getFieldKind = exports.rebaseRevisionMetadataFromInfo = exports.intoDelta = exports.updateRefreshers = exports.getBuildIds = exports.relevantRemovedRoots = exports.ModularChangeFamily = void 0;
8
8
  const internal_1 = require("@fluidframework/core-utils/internal");
9
9
  const sorted_btree_es6_1 = require("@tylerbu/sorted-btree-es6");
10
- const index_js_1 = require("../../core/index.js");
11
- const index_js_2 = require("../../util/index.js");
10
+ const internal_2 = require("@fluidframework/telemetry-utils/internal");
11
+ const index_js_1 = require("../../codec/index.js");
12
+ const index_js_2 = require("../../core/index.js");
13
+ const index_js_3 = require("../../util/index.js");
12
14
  const crossFieldQueries_js_1 = require("./crossFieldQueries.js");
13
15
  const fieldChangeHandler_js_1 = require("./fieldChangeHandler.js");
14
16
  const genericFieldKind_js_1 = require("./genericFieldKind.js");
15
17
  const modularChangeTypes_js_1 = require("./modularChangeTypes.js");
18
+ const semver_ts_1 = require("semver-ts");
19
+ const changeAtomIdBTree_js_1 = require("../changeAtomIdBTree.js");
16
20
  /**
17
21
  * Implementation of ChangeFamily which delegates work in a given field to the appropriate FieldKind
18
22
  * as determined by the schema.
19
23
  */
20
24
  class ModularChangeFamily {
21
- constructor(fieldKinds, codecs) {
25
+ constructor(fieldKinds, codecs, codecOptions) {
22
26
  this.codecs = codecs;
27
+ this.codecOptions = codecOptions;
23
28
  this.fieldKinds = fieldKinds;
24
29
  }
25
30
  get rebaser() {
@@ -34,9 +39,9 @@ class ModularChangeFamily {
34
39
  */
35
40
  normalizeFieldChanges(change1, change2) {
36
41
  // TODO: Handle the case where changes have conflicting field kinds
37
- const kind = change1.fieldKind !== genericFieldKind_js_1.genericFieldKind.identifier
38
- ? change1.fieldKind
39
- : change2.fieldKind;
42
+ const kind = change1.fieldKind === genericFieldKind_js_1.genericFieldKind.identifier
43
+ ? change2.fieldKind
44
+ : change1.fieldKind;
40
45
  if (kind === genericFieldKind_js_1.genericFieldKind.identifier) {
41
46
  // Both changes are generic
42
47
  return {
@@ -67,18 +72,22 @@ class ModularChangeFamily {
67
72
  return convertedChange;
68
73
  }
69
74
  compose(changes) {
70
- const { revInfos, maxId } = getRevInfoFromTaggedChanges(changes);
75
+ const { maxId } = getRevInfoFromTaggedChanges(changes);
71
76
  const idState = { maxId };
72
77
  const pairwiseDelegate = (left, right) => {
73
- return this.composePair(left, right, revInfos, idState);
78
+ return this.composePair(left, right, idState);
74
79
  };
75
80
  const innerChanges = changes.map((change) => change.change);
76
- return (0, index_js_2.balancedReduce)(innerChanges, pairwiseDelegate, makeModularChangeset);
81
+ return (0, index_js_3.balancedReduce)(innerChanges, pairwiseDelegate, makeModularChangeset);
77
82
  }
78
- composePair(change1, change2, revInfos, idState) {
79
- const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys } = this.composeAllFields(change1, change2, revInfos, idState);
83
+ composePair(change1, change2, idState) {
84
+ const revInfos = composeRevInfos(change1.revisions, change2.revisions);
85
+ const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys, rootNodes } = this.composeAllFields(change1, change2, revInfos, idState);
80
86
  const { allBuilds, allDestroys, allRefreshers } = composeBuildsDestroysAndRefreshers(change1, change2);
81
- return makeModularChangeset({
87
+ // The composed changeset has a "no change" constraint if either change has one
88
+ const noChangeConstraint = change1.noChangeConstraint ?? change2.noChangeConstraint;
89
+ const noChangeConstraintOnRevert = change1.noChangeConstraintOnRevert ?? change2.noChangeConstraintOnRevert;
90
+ const composed = makeModularChangeset({
82
91
  fieldChanges,
83
92
  nodeChanges,
84
93
  nodeToParent,
@@ -86,10 +95,16 @@ class ModularChangeFamily {
86
95
  crossFieldKeys,
87
96
  maxId: idState.maxId,
88
97
  revisions: revInfos,
98
+ rootNodes,
89
99
  builds: allBuilds,
90
100
  destroys: allDestroys,
91
101
  refreshers: allRefreshers,
102
+ noChangeConstraint,
103
+ noChangeConstraintOnRevert,
92
104
  });
105
+ // XXX: This is an expensive assert which should be disabled before merging.
106
+ validateChangeset(composed, this.fieldKinds);
107
+ return composed;
93
108
  }
94
109
  composeAllFields(potentiallyConflictedChange1, potentiallyConflictedChange2, revInfos, idState) {
95
110
  // Our current cell ordering scheme in sequences depends on being able to rebase over a change with conflicts.
@@ -97,8 +112,8 @@ class ModularChangeFamily {
97
112
  // TODO: remove once AB#46104 is completed
98
113
  const change1 = this.getEffectiveChange(potentiallyConflictedChange1);
99
114
  const change2 = this.getEffectiveChange(potentiallyConflictedChange2);
100
- const genId = (0, index_js_2.idAllocatorFromState)(idState);
101
- const revisionMetadata = (0, index_js_1.revisionMetadataSourceFromInfo)(revInfos);
115
+ const genId = (0, index_js_3.idAllocatorFromState)(idState);
116
+ const revisionMetadata = (0, index_js_2.revisionMetadataSourceFromInfo)(revInfos);
102
117
  // We merge nodeChanges, nodeToParent, and nodeAliases from the two changesets.
103
118
  // The merged tables will have correct entries for all nodes which are only referenced in one of the input changesets.
104
119
  // During composeFieldMaps and composeInvalidatedElements we will find all nodes referenced in both input changesets
@@ -107,38 +122,54 @@ class ModularChangeFamily {
107
122
  // A collision for a node ID means that that node is referenced in both changesets
108
123
  // (since we assume that if two changesets use the same node ID they are referring to the same node),
109
124
  // therefore all collisions will be addressed when processing the intersection of the changesets.
110
- const composedNodeChanges = (0, index_js_2.brand)((0, index_js_2.mergeTupleBTrees)(change1.nodeChanges, change2.nodeChanges));
111
- const composedNodeToParent = (0, index_js_2.brand)((0, index_js_2.mergeTupleBTrees)(change1.nodeToParent, change2.nodeToParent));
112
- const composedNodeAliases = (0, index_js_2.brand)((0, index_js_2.mergeTupleBTrees)(change1.nodeAliases, change2.nodeAliases));
113
- const crossFieldTable = newComposeTable(change1, change2, composedNodeToParent);
125
+ const composedNodeChanges = (0, index_js_3.brand)((0, index_js_3.mergeTupleBTrees)(change1.nodeChanges, change2.nodeChanges));
126
+ const composedNodeToParent = (0, index_js_3.brand)((0, index_js_3.mergeTupleBTrees)(change1.nodeToParent, change2.nodeToParent));
127
+ const composedNodeAliases = (0, index_js_3.brand)((0, index_js_3.mergeTupleBTrees)(change1.nodeAliases, change2.nodeAliases));
128
+ const pendingCompositions = {
129
+ nodeIdsToCompose: [],
130
+ affectedBaseFields: (0, index_js_3.newTupleBTree)(),
131
+ };
132
+ const movedCrossFieldKeys = (0, modularChangeTypes_js_1.newCrossFieldRangeTable)();
133
+ const removedCrossFieldKeys = (0, modularChangeTypes_js_1.newCrossFieldRangeTable)();
134
+ const composedRoots = composeRootTables(change1, change2, composedNodeToParent, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
135
+ const crossFieldTable = newComposeTable(change1, change2, composedRoots, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
114
136
  const composedFields = this.composeFieldMaps(change1.fieldChanges, change2.fieldChanges, undefined, genId, crossFieldTable, revisionMetadata);
115
137
  this.composeInvalidatedElements(crossFieldTable, composedFields, composedNodeChanges, composedNodeToParent, composedNodeAliases, genId, revisionMetadata);
116
- // Currently no field kinds require making changes to cross-field keys during composition, so we can just merge the two tables.
117
- const composedCrossFieldKeys = index_js_2.RangeMap.union(change1.crossFieldKeys, change2.crossFieldKeys);
138
+ for (const entry of crossFieldTable.renamesToDelete.entries()) {
139
+ deleteNodeRenameFrom(crossFieldTable.composedRootNodes, entry.start, entry.length);
140
+ }
141
+ for (const [nodeId, location] of crossFieldTable.movedNodeToParent.entries()) {
142
+ // Moved nodes are from change2.
143
+ // If there is a corresponding node in change1, then composedNodeToParent will already have the correct entry,
144
+ // because the location of the node is the same in change1 and the composed change
145
+ // (since they have the same input context).
146
+ if (crossFieldTable.newToBaseNodeId.get(nodeId) === undefined) {
147
+ composedNodeToParent.set(nodeId, location);
148
+ }
149
+ }
118
150
  return {
119
151
  fieldChanges: composedFields,
120
152
  nodeChanges: composedNodeChanges,
121
153
  nodeToParent: composedNodeToParent,
122
154
  nodeAliases: composedNodeAliases,
123
- crossFieldKeys: composedCrossFieldKeys,
155
+ crossFieldKeys: composeCrossFieldKeyTables(change1.crossFieldKeys, change2.crossFieldKeys, crossFieldTable.movedCrossFieldKeys, crossFieldTable.removedCrossFieldKeys),
156
+ rootNodes: composedRoots,
124
157
  };
125
158
  }
126
159
  composeInvalidatedField(fieldChange, crossFieldTable, genId, revisionMetadata) {
127
160
  const context = crossFieldTable.fieldToContext.get(fieldChange);
128
161
  (0, internal_1.assert)(context !== undefined, 0x8cc /* Should have context for every invalidated field */);
129
- const { fieldId, change1: fieldChange1, change2: fieldChange2, composedChange } = context;
162
+ const { change1: fieldChange1, change2: fieldChange2, composedChange } = context;
163
+ crossFieldTable.pendingCompositions.affectedBaseFields.delete(fieldIdKeyFromFieldId(context.fieldId));
130
164
  const rebaser = getChangeHandler(this.fieldKinds, composedChange.fieldKind).rebaser;
131
165
  const composeNodes = (child1, child2) => {
132
- if (child1 !== undefined &&
133
- child2 !== undefined &&
134
- getFromChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2) === undefined) {
135
- setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
136
- crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
166
+ if (child1 !== undefined && child2 !== undefined) {
167
+ addNodesToCompose(crossFieldTable, child1, child2);
137
168
  }
138
169
  return child1 ?? child2 ?? (0, internal_1.fail)(0xb22 /* Should not compose two undefined nodes */);
139
170
  };
140
- const amendedChange = rebaser.compose(fieldChange1, fieldChange2, composeNodes, genId, new ComposeManager(crossFieldTable, fieldChange, fieldId, false), revisionMetadata);
141
- composedChange.change = (0, index_js_2.brand)(amendedChange);
171
+ const amendedChange = rebaser.compose(fieldChange1, fieldChange2, composeNodes, genId, new ComposeNodeManagerI(crossFieldTable, context.fieldId, false), revisionMetadata);
172
+ composedChange.change = (0, index_js_3.brand)(amendedChange);
142
173
  }
143
174
  /**
144
175
  * Updates everything in the composed output which may no longer be valid.
@@ -146,32 +177,23 @@ class ModularChangeFamily {
146
177
  * - discovering that two node changesets refer to the same node (`nodeIdsToCompose`)
147
178
  * - a previously composed field being invalidated by a cross field effect (`invalidatedFields`)
148
179
  * - a field which was copied directly from an input changeset being invalidated by a cross field effect
149
- * (`affectedBaseFields` and `affectedNewFields`)
180
+ * (`affectedBaseFields`)
150
181
  *
151
182
  * Updating an element may invalidate further elements. This function runs until there is no more invalidation.
152
183
  */
153
184
  composeInvalidatedElements(table, composedFields, composedNodes, composedNodeToParent, nodeAliases, genId, metadata) {
154
185
  const pending = table.pendingCompositions;
155
- while (table.invalidatedFields.size > 0 ||
156
- pending.nodeIdsToCompose.length > 0 ||
157
- pending.affectedBaseFields.length > 0 ||
158
- pending.affectedNewFields.length > 0) {
159
- // Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
160
- for (const [id1, id2] of pending.nodeIdsToCompose) {
161
- this.composeNodesById(table.baseChange.nodeChanges, table.newChange.nodeChanges, composedNodes, composedNodeToParent, nodeAliases, id1, id2, genId, table, metadata);
162
- }
163
- pending.nodeIdsToCompose.length = 0;
164
- this.composeAffectedFields(table, table.baseChange, true, pending.affectedBaseFields, composedFields, composedNodes, genId, metadata);
165
- this.composeAffectedFields(table, table.newChange, false, pending.affectedNewFields, composedFields, composedNodes, genId, metadata);
166
- this.processInvalidatedCompositions(table, genId, metadata);
186
+ while (pending.nodeIdsToCompose.length > 0 || pending.affectedBaseFields.length > 0) {
187
+ this.processPendingNodeCompositions(table, composedNodes, composedNodeToParent, nodeAliases, genId, metadata);
188
+ this.composeAffectedFields(table, table.baseChange, pending.affectedBaseFields, composedFields, composedNodes, genId, metadata);
167
189
  }
168
190
  }
169
- processInvalidatedCompositions(table, genId, metadata) {
170
- const fieldsToUpdate = table.invalidatedFields;
171
- table.invalidatedFields = new Set();
172
- for (const fieldChange of fieldsToUpdate) {
173
- this.composeInvalidatedField(fieldChange, table, genId, metadata);
191
+ processPendingNodeCompositions(table, composedNodes, composedNodeToParent, nodeAliases, genId, metadata) {
192
+ // Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
193
+ for (const [id1, id2] of table.pendingCompositions.nodeIdsToCompose) {
194
+ this.composeNodesById(table.baseChange, table.newChange, composedNodes, composedNodeToParent, nodeAliases, id1, id2, genId, table, metadata);
174
195
  }
196
+ table.pendingCompositions.nodeIdsToCompose.length = 0;
175
197
  }
176
198
  /**
177
199
  * Ensures that each field in `affectedFields` has been updated in the composition output.
@@ -184,38 +206,36 @@ class ModularChangeFamily {
184
206
  * If not, they are assumed to be part of the new changeset.
185
207
  * @param affectedFields - The set of fields to process.
186
208
  */
187
- composeAffectedFields(table, change, areBaseFields, affectedFields, composedFields, composedNodes, genId, metadata) {
188
- for (const fieldIdKey of affectedFields.keys()) {
189
- const fieldId = normalizeFieldId(fieldIdFromFieldIdKey(fieldIdKey), change.nodeAliases);
190
- const fieldChange = fieldChangeFromId(change.fieldChanges, change.nodeChanges, fieldId);
209
+ composeAffectedFields(table, change, affectedFields, composedFields, composedNodes, genId, metadata) {
210
+ const fieldsToProcess = affectedFields.clone();
211
+ affectedFields.clear();
212
+ for (const fieldIdKey of fieldsToProcess.keys()) {
213
+ const fieldId = fieldIdFromFieldIdKey(fieldIdKey);
214
+ const fieldChange = fieldChangeFromId(change, fieldId);
191
215
  if (table.fieldToContext.has(fieldChange) ||
192
216
  table.newFieldToBaseField.has(fieldChange)) {
193
- // This function handles fields which were not part of the intersection of the two changesets but which need to be updated anyway.
194
- // If we've already processed this field then either it is up to date
195
- // or there is pending inval which will be handled in processInvalidatedCompositions.
196
- continue;
197
- }
198
- const emptyChange = this.createEmptyFieldChange(fieldChange.fieldKind);
199
- const [change1, change2] = areBaseFields
200
- ? [fieldChange, emptyChange]
201
- : [emptyChange, fieldChange];
202
- const composedField = this.composeFieldChanges(fieldId, change1, change2, genId, table, metadata);
203
- if (fieldId.nodeId === undefined) {
204
- composedFields.set(fieldId.field, composedField);
205
- continue;
217
+ this.composeInvalidatedField(fieldChange, table, genId, metadata);
206
218
  }
207
- const nodeId = getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId;
208
- let nodeChangeset = nodeChangeFromId(composedNodes, nodeId);
209
- if (!table.composedNodes.has(nodeChangeset)) {
210
- nodeChangeset = cloneNodeChangeset(nodeChangeset);
211
- setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
212
- }
213
- if (nodeChangeset.fieldChanges === undefined) {
214
- nodeChangeset.fieldChanges = new Map();
219
+ else {
220
+ this.composeFieldWithNoNewChange(table, fieldChange, fieldId, composedFields, composedNodes, genId, metadata);
215
221
  }
216
- nodeChangeset.fieldChanges.set(fieldId.field, composedField);
217
222
  }
218
- affectedFields.clear();
223
+ }
224
+ composeFieldWithNoNewChange(table, baseFieldChange, fieldId, composedFields, composedNodes, genId, metadata) {
225
+ const emptyChange = this.createEmptyFieldChange(baseFieldChange.fieldKind);
226
+ const composedField = this.composeFieldChanges(fieldId, baseFieldChange, emptyChange, genId, table, metadata);
227
+ if (fieldId.nodeId === undefined) {
228
+ composedFields.set(fieldId.field, composedField);
229
+ return;
230
+ }
231
+ const nodeId = normalizeNodeId((0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId, table.baseChange.nodeAliases);
232
+ // We clone the node changeset before mutating it, as it may be from one of the input changesets.
233
+ const nodeChangeset = cloneNodeChangeset(nodeChangeFromId(composedNodes, table.baseChange.nodeAliases, nodeId));
234
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(composedNodes, nodeId, nodeChangeset);
235
+ if (nodeChangeset.fieldChanges === undefined) {
236
+ nodeChangeset.fieldChanges = new Map();
237
+ }
238
+ nodeChangeset.fieldChanges.set(fieldId.field, composedField);
219
239
  }
220
240
  composeFieldMaps(change1, change2, parentId, genId, crossFieldTable, revisionMetadata) {
221
241
  const composedFields = new Map();
@@ -225,9 +245,17 @@ class ModularChangeFamily {
225
245
  for (const [field, fieldChange1] of change1) {
226
246
  const fieldId = { nodeId: parentId, field };
227
247
  const fieldChange2 = change2.get(field);
228
- const composedField = fieldChange2 !== undefined
229
- ? this.composeFieldChanges(fieldId, fieldChange1, fieldChange2, genId, crossFieldTable, revisionMetadata)
230
- : fieldChange1;
248
+ const cachedComposedFieldChange = crossFieldTable.fieldToContext.get(fieldChange1)?.composedChange;
249
+ if (fieldChange2 === undefined && cachedComposedFieldChange !== undefined) {
250
+ // This can happen if the field was previous processed in `composeFieldWithNoNewChange`.
251
+ // If `change2` does not have a change for this field, then without this check we would
252
+ // lose the composed field change and instead simply have `change1`'s change.
253
+ composedFields.set(field, cachedComposedFieldChange);
254
+ continue;
255
+ }
256
+ const composedField = fieldChange2 === undefined
257
+ ? fieldChange1
258
+ : this.composeFieldChanges(fieldId, fieldChange1, fieldChange2, genId, crossFieldTable, revisionMetadata);
231
259
  composedFields.set(field, composedField);
232
260
  }
233
261
  for (const [field, fieldChange2] of change2) {
@@ -244,23 +272,22 @@ class ModularChangeFamily {
244
272
  * will be added to `crossFieldTable.pendingCompositions.nodeIdsToCompose`.
245
273
  *
246
274
  * Any fields which had cross-field information sent to them as part of this field composition
247
- * will be added to either `affectedBaseFields` or `affectedNewFields` in `crossFieldTable.pendingCompositions`.
275
+ * will be added to `affectedBaseFields` in `crossFieldTable.pendingCompositions`.
248
276
  *
249
277
  * Any composed `FieldChange` which is invalidated by new cross-field information will be added to `crossFieldTable.invalidatedFields`.
250
278
  */
251
279
  composeFieldChanges(fieldId, change1, change2, idAllocator, crossFieldTable, revisionMetadata) {
252
280
  const { fieldKind, changeHandler, change1: change1Normalized, change2: change2Normalized, } = this.normalizeFieldChanges(change1, change2);
253
- const manager = new ComposeManager(crossFieldTable, change1, fieldId);
281
+ const manager = new ComposeNodeManagerI(crossFieldTable, fieldId);
254
282
  const composedChange = changeHandler.rebaser.compose(change1Normalized, change2Normalized, (child1, child2) => {
255
283
  if (child1 !== undefined && child2 !== undefined) {
256
- setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
257
- crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
284
+ addNodesToCompose(crossFieldTable, child1, child2);
258
285
  }
259
286
  return child1 ?? child2 ?? (0, internal_1.fail)(0xb23 /* Should not compose two undefined nodes */);
260
287
  }, idAllocator, manager, revisionMetadata);
261
288
  const composedField = {
262
289
  fieldKind,
263
- change: (0, index_js_2.brand)(composedChange),
290
+ change: (0, index_js_3.brand)(composedChange),
264
291
  };
265
292
  crossFieldTable.fieldToContext.set(change1, {
266
293
  fieldId,
@@ -271,19 +298,18 @@ class ModularChangeFamily {
271
298
  crossFieldTable.newFieldToBaseField.set(change2, change1);
272
299
  return composedField;
273
300
  }
274
- composeNodesById(nodeChanges1, nodeChanges2, composedNodes, composedNodeToParent, nodeAliases, id1, id2, idAllocator, crossFieldTable, revisionMetadata) {
275
- const nodeChangeset1 = nodeChangeFromId(nodeChanges1, id1);
276
- const nodeChangeset2 = nodeChangeFromId(nodeChanges2, id2);
301
+ composeNodesById(change1, change2, composedNodes, composedNodeToParent, composedAliases, id1, id2, idAllocator, crossFieldTable, revisionMetadata) {
302
+ const nodeChangeset1 = nodeChangeFromId(change1.nodeChanges, change1.nodeAliases, id1);
303
+ const nodeChangeset2 = nodeChangeFromId(change2.nodeChanges, change2.nodeAliases, id2);
277
304
  const composedNodeChangeset = this.composeNodeChanges(id1, nodeChangeset1, nodeChangeset2, idAllocator, crossFieldTable, revisionMetadata);
278
- setInChangeAtomIdMap(composedNodes, id1, composedNodeChangeset);
279
- if (!(0, index_js_1.areEqualChangeAtomIds)(id1, id2)) {
305
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(composedNodes, id1, composedNodeChangeset);
306
+ if (!(0, index_js_2.areEqualChangeAtomIds)(id1, id2)) {
280
307
  composedNodes.delete([id2.revision, id2.localId]);
281
308
  composedNodeToParent.delete([id2.revision, id2.localId]);
282
- setInChangeAtomIdMap(nodeAliases, id2, id1);
309
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(composedAliases, id2, id1);
283
310
  // We need to delete id1 to avoid forming a cycle in case id1 already had an alias.
284
- nodeAliases.delete([id1.revision, id1.localId]);
311
+ composedAliases.delete([id1.revision, id1.localId]);
285
312
  }
286
- crossFieldTable.composedNodes.add(composedNodeChangeset);
287
313
  }
288
314
  composeNodeChanges(nodeId, change1, change2, genId, crossFieldTable, revisionMetadata) {
289
315
  // WARNING: this composition logic assumes that we never make compositions of the following form:
@@ -314,8 +340,8 @@ class ModularChangeFamily {
314
340
  /**
315
341
  * @param change - The change to invert.
316
342
  * @param isRollback - Whether the inverted change is meant to rollback a change on a branch as is the case when
317
- * @param revisionForInvert - The revision for the invert changeset.
318
343
  * performing a sandwich rebase.
344
+ * @param revisionForInvert - The revision for the invert changeset.
319
345
  */
320
346
  invert(change, isRollback, revisionForInvert) {
321
347
  // Rollback changesets destroy the nodes created by the change being rolled back.
@@ -325,6 +351,8 @@ class ModularChangeFamily {
325
351
  const revInfos = isRollback
326
352
  ? [{ revision: revisionForInvert, rollbackOf: change.revision }]
327
353
  : [{ revision: revisionForInvert }];
354
+ const noChangeConstraint = change.change.noChangeConstraintOnRevert;
355
+ const noChangeConstraintOnRevert = change.change.noChangeConstraint;
328
356
  if (hasConflicts(change.change)) {
329
357
  return makeModularChangeset({
330
358
  maxId: change.change.maxId,
@@ -332,16 +360,21 @@ class ModularChangeFamily {
332
360
  destroys,
333
361
  });
334
362
  }
335
- const genId = (0, index_js_2.idAllocatorFromMaxId)(change.change.maxId ?? -1);
363
+ const genId = (0, index_js_3.idAllocatorFromMaxId)(change.change.maxId ?? -1);
336
364
  const crossFieldTable = {
337
- ...newCrossFieldTable(),
365
+ change: change.change,
366
+ entries: (0, index_js_2.newChangeAtomIdRangeMap)(),
338
367
  originalFieldToContext: new Map(),
339
- invertedNodeToParent: (0, index_js_2.brand)(change.change.nodeToParent.clone()),
368
+ invertRevision: revisionForInvert,
369
+ invertedNodeToParent: (0, index_js_3.brand)(change.change.nodeToParent.clone()),
370
+ invalidatedFields: new Set(),
371
+ invertedRoots: invertRootTable(change.change, isRollback),
372
+ attachToDetachId: (0, index_js_2.newChangeAtomIdTransform)(),
340
373
  };
341
374
  const { revInfos: oldRevInfos } = getRevInfoFromTaggedChanges([change]);
342
- const revisionMetadata = (0, index_js_1.revisionMetadataSourceFromInfo)(oldRevInfos);
375
+ const revisionMetadata = (0, index_js_2.revisionMetadataSourceFromInfo)(oldRevInfos);
343
376
  const invertedFields = this.invertFieldMap(change.change.fieldChanges, undefined, isRollback, genId, crossFieldTable, revisionMetadata, revisionForInvert);
344
- const invertedNodes = (0, index_js_2.newTupleBTree)();
377
+ const invertedNodes = (0, index_js_3.newTupleBTree)();
345
378
  change.change.nodeChanges.forEachPair(([revision, localId], nodeChangeset) => {
346
379
  invertedNodes.set([revision, localId], this.invertNodeChange(nodeChangeset, { revision, localId }, isRollback, genId, crossFieldTable, revisionMetadata, revisionForInvert));
347
380
  });
@@ -352,22 +385,26 @@ class ModularChangeFamily {
352
385
  const originalFieldChange = fieldChange.change;
353
386
  const context = crossFieldTable.originalFieldToContext.get(fieldChange);
354
387
  (0, internal_1.assert)(context !== undefined, 0x851 /* Should have context for every invalidated field */);
355
- const { invertedField, fieldId } = context;
356
- const amendedChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.invert(originalFieldChange, isRollback, genId, revisionForInvert, new InvertManager(crossFieldTable, fieldChange, fieldId), revisionMetadata);
357
- invertedField.change = (0, index_js_2.brand)(amendedChange);
388
+ const { invertedField } = context;
389
+ const amendedChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.invert(originalFieldChange, isRollback, genId, revisionForInvert, new InvertNodeManagerI(crossFieldTable, context.fieldId), revisionMetadata);
390
+ invertedField.change = (0, index_js_3.brand)(amendedChange);
358
391
  }
359
392
  }
360
393
  const crossFieldKeys = this.makeCrossFieldKeyTable(invertedFields, invertedNodes);
394
+ this.processInvertRenames(crossFieldTable);
361
395
  return makeModularChangeset({
362
396
  fieldChanges: invertedFields,
363
397
  nodeChanges: invertedNodes,
364
398
  nodeToParent: crossFieldTable.invertedNodeToParent,
399
+ rootNodes: crossFieldTable.invertedRoots,
365
400
  nodeAliases: change.change.nodeAliases,
366
401
  crossFieldKeys,
367
402
  maxId: genId.getMaxId(),
368
403
  revisions: revInfos,
369
404
  constraintViolationCount: change.change.constraintViolationCountOnRevert,
370
405
  constraintViolationCountOnRevert: change.change.constraintViolationCount,
406
+ noChangeConstraint,
407
+ noChangeConstraintOnRevert,
371
408
  destroys,
372
409
  });
373
410
  }
@@ -375,11 +412,11 @@ class ModularChangeFamily {
375
412
  const invertedFields = new Map();
376
413
  for (const [field, fieldChange] of changes) {
377
414
  const fieldId = { nodeId: parentId, field };
378
- const manager = new InvertManager(crossFieldTable, fieldChange, fieldId);
415
+ const manager = new InvertNodeManagerI(crossFieldTable, fieldId);
379
416
  const invertedChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.invert(fieldChange.change, isRollback, genId, revisionForInvert, manager, revisionMetadata);
380
417
  const invertedFieldChange = {
381
418
  ...fieldChange,
382
- change: (0, index_js_2.brand)(invertedChange),
419
+ change: (0, index_js_3.brand)(invertedChange),
383
420
  };
384
421
  invertedFields.set(field, invertedFieldChange);
385
422
  crossFieldTable.originalFieldToContext.set(fieldChange, {
@@ -407,27 +444,42 @@ class ModularChangeFamily {
407
444
  }
408
445
  return inverse;
409
446
  }
447
+ processInvertRenames(table) {
448
+ for (const { start: newAttachId, value: originalDetachId, length, } of table.attachToDetachId.entries()) {
449
+ // Note that the detach location is already set in `invertDetach`.
450
+ addNodeRename(table.invertedRoots, originalDetachId, newAttachId, length, undefined);
451
+ }
452
+ }
410
453
  rebase(taggedChange, potentiallyConflictedOver, revisionMetadata) {
411
454
  // Our current cell ordering scheme in sequences depends on being able to rebase over a change with conflicts.
412
455
  // This means that we must rebase over a muted version of the conflicted changeset.
413
456
  // That is, a version that includes its declarations (e.g., new cells) but not its changes.
414
457
  // TODO: remove once AB#46104 is completed
415
- const over = (0, index_js_1.mapTaggedChange)(potentiallyConflictedOver, this.getEffectiveChange(potentiallyConflictedOver.change));
458
+ const over = (0, index_js_2.mapTaggedChange)(potentiallyConflictedOver, this.getEffectiveChange(potentiallyConflictedOver.change));
416
459
  const change = taggedChange.change;
417
460
  const maxId = Math.max(change.maxId ?? -1, over.change.maxId ?? -1);
418
461
  const idState = { maxId };
419
- const genId = (0, index_js_2.idAllocatorFromState)(idState);
462
+ const genId = (0, index_js_3.idAllocatorFromState)(idState);
463
+ const affectedBaseFields = (0, index_js_3.newTupleBTree)();
464
+ const nodesToRebase = [];
465
+ const rebasedNodeToParent = (0, index_js_3.brand)(change.nodeToParent.clone());
466
+ const rebaseVersion = Math.max(change.rebaseVersion, over.change.rebaseVersion);
467
+ const rebasedRootNodes = rebaseRoots(change, over.change, affectedBaseFields, nodesToRebase, rebasedNodeToParent, rebaseVersion);
420
468
  const crossFieldTable = {
421
- ...newCrossFieldTable(),
469
+ rebaseVersion,
470
+ entries: newDetachedEntryMap(),
422
471
  newChange: change,
423
472
  baseChange: over.change,
424
473
  baseFieldToContext: new Map(),
425
- baseToRebasedNodeId: (0, index_js_2.newTupleBTree)(),
474
+ baseRoots: over.change.rootNodes,
475
+ rebasedRootNodes,
476
+ baseToRebasedNodeId: (0, index_js_3.newTupleBTree)(),
426
477
  rebasedFields: new Set(),
427
- rebasedNodeToParent: (0, index_js_2.brand)(change.nodeToParent.clone()),
428
- rebasedCrossFieldKeys: change.crossFieldKeys.clone(),
478
+ rebasedNodeToParent,
479
+ rebasedDetachLocations: (0, index_js_2.newChangeAtomIdRangeMap)(),
480
+ movedDetaches: (0, index_js_2.newChangeAtomIdRangeMap)(),
429
481
  nodeIdPairs: [],
430
- affectedBaseFields: (0, index_js_2.newTupleBTree)(),
482
+ affectedBaseFields,
431
483
  fieldsWithUnattachedChild: new Set(),
432
484
  };
433
485
  const getBaseRevisions = () => revisionInfoFromTaggedChange(over).map((info) => info.revision);
@@ -436,177 +488,208 @@ class ModularChangeFamily {
436
488
  getRevisionToRebase: () => taggedChange.revision,
437
489
  getBaseRevisions,
438
490
  };
439
- const rebasedNodes = (0, index_js_2.brand)(change.nodeChanges.clone());
440
- const rebasedFields = this.rebaseIntersectingFields(crossFieldTable, rebasedNodes, genId, rebaseMetadata);
441
- this.rebaseInvalidatedElements(rebasedFields, rebasedNodes, crossFieldTable, rebaseMetadata, genId);
491
+ const rebasedNodes = (0, index_js_3.brand)(change.nodeChanges.clone());
492
+ const rebasedFields = this.rebaseIntersectingFields(nodesToRebase, crossFieldTable, rebasedNodes, genId, rebaseMetadata);
493
+ this.rebaseInvalidatedFields(rebasedFields, rebasedNodes, crossFieldTable, rebaseMetadata, genId);
494
+ fixupRebasedDetachLocations(crossFieldTable);
442
495
  const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
443
496
  const revertConstraintState = newConstraintState(change.constraintViolationCountOnRevert ?? 0);
444
- this.updateConstraintsForFields(rebasedFields, fieldChangeHandler_js_1.NodeAttachState.Attached, fieldChangeHandler_js_1.NodeAttachState.Attached, constraintState, revertConstraintState, rebasedNodes);
497
+ let noChangeConstraint = change.noChangeConstraint;
498
+ if (noChangeConstraint !== undefined && !noChangeConstraint.violated) {
499
+ noChangeConstraint = { violated: true };
500
+ constraintState.violationCount += 1;
501
+ }
502
+ this.updateConstraints(rebasedFields, rebasedNodes, rebasedRootNodes, constraintState, revertConstraintState);
503
+ const fieldsWithRootMoves = getFieldsWithRootMoves(crossFieldTable.rebasedRootNodes, change.nodeAliases);
504
+ const fieldToRootChanges = getFieldToRootChanges(crossFieldTable.rebasedRootNodes, change.nodeAliases);
445
505
  const rebased = makeModularChangeset({
446
- fieldChanges: this.pruneFieldMap(rebasedFields, rebasedNodes),
506
+ fieldChanges: this.pruneFieldMap(rebasedFields, undefined, rebasedNodes, crossFieldTable.rebasedNodeToParent, change.nodeAliases, crossFieldTable.rebasedRootNodes, fieldsWithRootMoves, fieldToRootChanges),
447
507
  nodeChanges: rebasedNodes,
448
508
  nodeToParent: crossFieldTable.rebasedNodeToParent,
509
+ rootNodes: this.pruneRoots(crossFieldTable.rebasedRootNodes, rebasedNodes, crossFieldTable.rebasedNodeToParent, change.nodeAliases, fieldsWithRootMoves, fieldToRootChanges),
510
+ // TODO: Do we need to include aliases for node changesets added during rebasing?
449
511
  nodeAliases: change.nodeAliases,
450
- crossFieldKeys: crossFieldTable.rebasedCrossFieldKeys,
512
+ crossFieldKeys: rebaseCrossFieldKeys(change.crossFieldKeys, crossFieldTable.movedDetaches, crossFieldTable.rebasedDetachLocations),
451
513
  maxId: idState.maxId,
452
514
  revisions: change.revisions,
453
515
  constraintViolationCount: constraintState.violationCount,
454
516
  constraintViolationCountOnRevert: revertConstraintState.violationCount,
517
+ noChangeConstraint,
518
+ noChangeConstraintOnRevert: change.noChangeConstraintOnRevert,
455
519
  builds: change.builds,
456
520
  destroys: change.destroys,
457
521
  refreshers: change.refreshers,
522
+ rebaseVersion,
458
523
  });
524
+ // XXX: This is an expensive assert which should be disabled before merging.
525
+ validateChangeset(rebased, this.fieldKinds);
459
526
  return rebased;
460
527
  }
461
528
  // This performs a first pass on all fields which have both new and base changes.
462
529
  // TODO: Can we also handle additional passes in this method?
463
- rebaseIntersectingFields(crossFieldTable, rebasedNodes, genId, metadata) {
530
+ rebaseIntersectingFields(rootChanges, crossFieldTable, rebasedNodes, genId, metadata) {
464
531
  const change = crossFieldTable.newChange;
465
532
  const baseChange = crossFieldTable.baseChange;
466
533
  const rebasedFields = this.rebaseFieldMap(change.fieldChanges, baseChange.fieldChanges, undefined, genId, crossFieldTable, metadata);
534
+ for (const [newChildChange, baseChildChange] of rootChanges) {
535
+ const rebasedNode = this.rebaseNodeChange(newChildChange, baseChildChange, genId, crossFieldTable, metadata);
536
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(rebasedNodes, newChildChange, rebasedNode);
537
+ }
467
538
  // This loop processes all fields which have both base and new changes.
468
539
  // Note that the call to `rebaseNodeChange` can add entries to `crossFieldTable.nodeIdPairs`.
469
540
  for (const [newId, baseId, _attachState] of crossFieldTable.nodeIdPairs) {
470
541
  const rebasedNode = this.rebaseNodeChange(newId, baseId, genId, crossFieldTable, metadata);
471
- setInChangeAtomIdMap(rebasedNodes, newId, rebasedNode);
542
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(rebasedNodes, newId, rebasedNode);
472
543
  }
473
544
  return rebasedFields;
474
545
  }
475
- // This processes fields which have no new changes but have been invalidated by another field.
476
- rebaseFieldsWithoutNewChanges(rebasedFields, rebasedNodes, crossFieldTable, genId, metadata) {
477
- const baseChange = crossFieldTable.baseChange;
478
- for (const [revision, localId, fieldKey] of crossFieldTable.affectedBaseFields.keys()) {
479
- const baseNodeId = localId !== undefined
480
- ? normalizeNodeId({ revision, localId }, baseChange.nodeAliases)
481
- : undefined;
482
- const baseFieldChange = fieldMapFromNodeId(baseChange.fieldChanges, baseChange.nodeChanges, baseNodeId).get(fieldKey);
483
- (0, internal_1.assert)(baseFieldChange !== undefined, 0x9c2 /* Cross field key registered for empty field */);
484
- if (crossFieldTable.baseFieldToContext.has(baseFieldChange)) {
485
- // This field has already been processed because there were changes to rebase.
486
- continue;
487
- }
488
- // This field has no changes in the new changeset, otherwise it would have been added to
489
- // `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
490
- const rebaseChild = (child, baseChild, stateChange) => {
491
- (0, internal_1.assert)(child === undefined, 0x9c3 /* There should be no new changes in this field */);
546
+ rebaseFieldWithoutNewChanges(baseFieldChange, baseFieldId, crossFieldTable, rebasedFields, rebasedNodes, genId, metadata,
547
+ /**
548
+ * The ID of a node in `baseFieldChange` which should be included in the rebased field change.
549
+ */
550
+ baseNodeId) {
551
+ // This field has no changes in the new changeset, otherwise it would have been added to
552
+ // `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
553
+ const rebaseChild = (child, baseChild, stateChange) => {
554
+ (0, internal_1.assert)(child === undefined, 0x9c3 /* There should be no new changes in this field */);
555
+ if (baseChild === undefined || baseNodeId === undefined) {
492
556
  return undefined;
493
- };
494
- const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
495
- const fieldChange = {
496
- ...baseFieldChange,
497
- change: (0, index_js_2.brand)(handler.createEmpty()),
498
- };
499
- const rebasedNodeId = baseNodeId !== undefined
500
- ? rebasedNodeIdFromBaseNodeId(crossFieldTable, baseNodeId)
557
+ }
558
+ return (0, index_js_2.areEqualChangeAtomIds)(normalizeNodeId(baseChild, crossFieldTable.baseChange.nodeAliases), baseNodeId)
559
+ ? baseNodeId
501
560
  : undefined;
502
- const fieldId = { nodeId: rebasedNodeId, field: fieldKey };
503
- const rebasedField = handler.rebaser.rebase(fieldChange.change, baseFieldChange.change, rebaseChild, genId, new RebaseManager(crossFieldTable, baseFieldChange, fieldId), metadata);
504
- const rebasedFieldChange = {
505
- ...baseFieldChange,
506
- change: (0, index_js_2.brand)(rebasedField),
507
- };
508
- // TODO: Deduplicate
509
- crossFieldTable.baseFieldToContext.set(baseFieldChange, {
510
- newChange: fieldChange,
511
- baseChange: baseFieldChange,
512
- rebasedChange: rebasedFieldChange,
513
- fieldId,
514
- baseNodeIds: [],
515
- });
516
- crossFieldTable.rebasedFields.add(rebasedFieldChange);
517
- this.attachRebasedField(rebasedFields, rebasedNodes, crossFieldTable, rebasedFieldChange, fieldId, genId, metadata);
518
- }
519
- }
520
- rebaseInvalidatedElements(rebasedFields, rebasedNodes, table, metadata, idAllocator) {
521
- this.rebaseFieldsWithoutNewChanges(rebasedFields, rebasedNodes, table, idAllocator, metadata);
522
- this.rebaseFieldsWithUnattachedChild(table, metadata, idAllocator);
523
- this.rebaseInvalidatedFields(table, metadata, idAllocator);
524
- }
525
- rebaseInvalidatedFields(crossFieldTable, rebaseMetadata, genId) {
526
- const fieldsToUpdate = crossFieldTable.invalidatedFields;
527
- crossFieldTable.invalidatedFields = new Set();
528
- for (const field of fieldsToUpdate) {
529
- this.rebaseInvalidatedField(field, crossFieldTable, rebaseMetadata, genId);
530
- }
531
- }
532
- rebaseFieldsWithUnattachedChild(table, metadata, idAllocator) {
533
- for (const field of table.fieldsWithUnattachedChild) {
534
- table.invalidatedFields.delete(field);
535
- this.rebaseInvalidatedField(field, table, metadata, idAllocator, true);
561
+ };
562
+ const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
563
+ const fieldChange = {
564
+ ...baseFieldChange,
565
+ change: (0, index_js_3.brand)(handler.createEmpty()),
566
+ };
567
+ const rebasedNodeId = baseFieldId.nodeId === undefined
568
+ ? undefined
569
+ : rebasedNodeIdFromBaseNodeId(crossFieldTable, baseFieldId.nodeId);
570
+ const fieldId = { nodeId: rebasedNodeId, field: baseFieldId.field };
571
+ const rebasedField = handler.rebaser.rebase(fieldChange.change, baseFieldChange.change, rebaseChild, genId, new RebaseNodeManagerI(crossFieldTable, fieldId), metadata, crossFieldTable.rebaseVersion);
572
+ const rebasedFieldChange = {
573
+ ...baseFieldChange,
574
+ change: (0, index_js_3.brand)(rebasedField),
575
+ };
576
+ const context = {
577
+ newChange: fieldChange,
578
+ baseChange: baseFieldChange,
579
+ rebasedChange: rebasedFieldChange,
580
+ fieldId,
581
+ baseNodeIds: (0, index_js_3.newTupleBTree)(),
582
+ };
583
+ if (baseNodeId !== undefined) {
584
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(context.baseNodeIds, baseNodeId, true);
585
+ }
586
+ crossFieldTable.baseFieldToContext.set(baseFieldChange, context);
587
+ crossFieldTable.rebasedFields.add(rebasedFieldChange);
588
+ this.attachRebasedField(rebasedFields, rebasedNodes, crossFieldTable, rebasedFieldChange, fieldId, genId, metadata);
589
+ }
590
+ rebaseInvalidatedFields(rebasedFields, rebasedNodes, crossFieldTable, rebaseMetadata, genId) {
591
+ while (crossFieldTable.affectedBaseFields.size > 0) {
592
+ const baseFields = crossFieldTable.affectedBaseFields.clone();
593
+ crossFieldTable.affectedBaseFields.clear();
594
+ for (const baseFieldIdKey of baseFields.keys()) {
595
+ const baseFieldId = normalizeFieldId(fieldIdFromFieldIdKey(baseFieldIdKey), crossFieldTable.baseChange.nodeAliases);
596
+ const baseField = fieldChangeFromId(crossFieldTable.baseChange, baseFieldId);
597
+ (0, internal_1.assert)(baseField !== undefined, 0x9c2 /* Cross field key registered for empty field */);
598
+ const context = crossFieldTable.baseFieldToContext.get(baseField);
599
+ if (context === undefined) {
600
+ this.rebaseFieldWithoutNewChanges(baseField, baseFieldId, crossFieldTable, rebasedFields, rebasedNodes, genId, rebaseMetadata);
601
+ }
602
+ else {
603
+ this.rebaseInvalidatedField(baseField, crossFieldTable, context, rebaseMetadata, genId);
604
+ }
605
+ }
536
606
  }
537
607
  }
538
- rebaseInvalidatedField(baseField, crossFieldTable, rebaseMetadata, genId, allowInval = false) {
539
- const context = crossFieldTable.baseFieldToContext.get(baseField);
540
- (0, internal_1.assert)(context !== undefined, 0x852 /* Every field should have a context */);
608
+ rebaseInvalidatedField(baseField, crossFieldTable, context, rebaseMetadata, genId) {
541
609
  const { changeHandler, change1: fieldChangeset, change2: baseChangeset, } = this.normalizeFieldChanges(context.newChange, context.baseChange);
542
610
  const rebaseChild = (curr, base) => {
543
611
  if (curr !== undefined) {
544
612
  return curr;
545
613
  }
546
- if (base !== undefined) {
547
- for (const id of context.baseNodeIds) {
548
- if ((0, index_js_1.areEqualChangeAtomIds)(base, id)) {
549
- return base;
550
- }
551
- }
614
+ if (base !== undefined && (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(context.baseNodeIds, base) === true) {
615
+ return base;
552
616
  }
553
617
  return undefined;
554
618
  };
555
- context.rebasedChange.change = (0, index_js_2.brand)(changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, new RebaseManager(crossFieldTable, baseField, context.fieldId, allowInval), rebaseMetadata));
619
+ let allowInval = false;
620
+ if (crossFieldTable.fieldsWithUnattachedChild.has(baseField)) {
621
+ crossFieldTable.fieldsWithUnattachedChild.delete(baseField);
622
+ allowInval = true;
623
+ }
624
+ context.rebasedChange.change = (0, index_js_3.brand)(changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, new RebaseNodeManagerI(crossFieldTable, context.fieldId, allowInval), rebaseMetadata, crossFieldTable.rebaseVersion));
556
625
  }
557
626
  attachRebasedField(rebasedFields, rebasedNodes, table, rebasedField, { nodeId, field: fieldKey }, idAllocator, metadata) {
558
627
  if (nodeId === undefined) {
559
628
  rebasedFields.set(fieldKey, rebasedField);
560
629
  return;
561
630
  }
562
- const rebasedNode = getFromChangeAtomIdMap(rebasedNodes, nodeId);
631
+ const rebasedNode = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(rebasedNodes, nodeId);
563
632
  if (rebasedNode !== undefined) {
564
- if (rebasedNode.fieldChanges === undefined) {
565
- rebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
633
+ const updatedRebasedNode = cloneNodeChangeset(rebasedNode);
634
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(rebasedNodes, nodeId, updatedRebasedNode);
635
+ if (updatedRebasedNode.fieldChanges === undefined) {
636
+ updatedRebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
566
637
  return;
567
638
  }
568
- (0, internal_1.assert)(!rebasedNode.fieldChanges.has(fieldKey), 0x9c4 /* Expected an empty field */);
569
- rebasedNode.fieldChanges.set(fieldKey, rebasedField);
639
+ (0, internal_1.assert)(!updatedRebasedNode.fieldChanges.has(fieldKey), 0x9c4 /* Expected an empty field */);
640
+ updatedRebasedNode.fieldChanges.set(fieldKey, rebasedField);
570
641
  return;
571
642
  }
572
643
  const newNode = {
573
644
  fieldChanges: new Map([[fieldKey, rebasedField]]),
574
645
  };
575
- setInChangeAtomIdMap(rebasedNodes, nodeId, newNode);
576
- setInChangeAtomIdMap(table.baseToRebasedNodeId, nodeId, nodeId);
577
- const parentFieldId = getParentFieldId(table.baseChange, nodeId);
578
- this.attachRebasedNode(rebasedFields, rebasedNodes, table, nodeId, parentFieldId, idAllocator, metadata);
579
- }
580
- attachRebasedNode(rebasedFields, rebasedNodes, table, baseNodeId, parentFieldIdBase, idAllocator, metadata) {
581
- const baseFieldChange = fieldChangeFromId(table.baseChange.fieldChanges, table.baseChange.nodeChanges, parentFieldIdBase);
646
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(rebasedNodes, nodeId, newNode);
647
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(table.baseToRebasedNodeId, nodeId, nodeId);
648
+ const parentBase = getNodeParent(table.baseChange, nodeId);
649
+ this.attachRebasedNode(rebasedFields, rebasedNodes, table, nodeId, parentBase, idAllocator, metadata);
650
+ }
651
+ attachRebasedNode(rebasedFields, rebasedNodes, table, baseNodeId, parentBase, idAllocator, metadata) {
652
+ if (parentBase.root !== undefined) {
653
+ const renamedRoot = firstAttachIdFromDetachId(table.baseChange.rootNodes, parentBase.root, 1).value;
654
+ const attachField = table.baseChange.crossFieldKeys.getFirst({ ...renamedRoot, target: crossFieldQueries_js_1.CrossFieldTarget.Destination }, 1).value;
655
+ if (attachField === undefined) {
656
+ const baseDetachLocation = table.baseChange.rootNodes.detachLocations.getFirst(parentBase.root, 1).value;
657
+ assignRootChange(table.rebasedRootNodes, table.rebasedNodeToParent, renamedRoot, baseNodeId, baseDetachLocation, table.rebaseVersion);
658
+ // We need to make sure the rebased changeset includes the detach location,
659
+ // so we add that field to `affectedBaseFields` unless it's already been processed.
660
+ if (baseDetachLocation !== undefined &&
661
+ !table.baseFieldToContext.has(fieldChangeFromId(table.baseChange, baseDetachLocation))) {
662
+ table.affectedBaseFields.set(fieldIdKeyFromFieldId(baseDetachLocation), true);
663
+ }
664
+ }
665
+ else {
666
+ // The base change inserts this node into `attachField`, so the rebased change should represent this node there.
667
+ const normalizedAttachField = normalizeFieldId(attachField, table.baseChange.nodeAliases);
668
+ const entry = table.entries.getFirst(renamedRoot, 1).value ?? {};
669
+ table.entries.set(renamedRoot, 1, { ...entry, nodeChange: baseNodeId });
670
+ table.affectedBaseFields.set(fieldIdKeyFromFieldId(normalizedAttachField), true);
671
+ this.attachRebasedNode(rebasedFields, rebasedNodes, table, baseNodeId, { field: normalizedAttachField }, idAllocator, metadata);
672
+ }
673
+ return;
674
+ }
675
+ const parentFieldIdBase = parentBase.field;
676
+ const baseFieldChange = fieldChangeFromId(table.baseChange, parentFieldIdBase);
582
677
  const rebasedFieldId = rebasedFieldIdFromBaseId(table, parentFieldIdBase);
583
- setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, rebasedFieldId);
678
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(table.rebasedNodeToParent, baseNodeId, { field: rebasedFieldId });
584
679
  const context = table.baseFieldToContext.get(baseFieldChange);
585
680
  if (context !== undefined) {
586
681
  // We've already processed this field.
587
- // The new child node will be attached in rebaseFieldsWithUnattachedChild.
588
- context.baseNodeIds.push(baseNodeId);
589
- table.fieldsWithUnattachedChild.add(baseFieldChange);
682
+ // The new child node will be attached in the next pass.
683
+ // Note that adding to `fieldsWithUnattachedChild` allows that field to generate new invalidations,
684
+ // so to avoid invalidation cycles we make sure we only add to it once per new unattached child.
685
+ // This is done by checking whether `context.baseNodeIds` already contained `baseNodeId`.
686
+ if ((0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(context.baseNodeIds, baseNodeId, true)) {
687
+ table.fieldsWithUnattachedChild.add(baseFieldChange);
688
+ table.affectedBaseFields.set(fieldIdKeyFromFieldId(parentFieldIdBase), true);
689
+ }
590
690
  return;
591
691
  }
592
- const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
593
- const fieldChange = {
594
- ...baseFieldChange,
595
- change: (0, index_js_2.brand)(handler.createEmpty()),
596
- };
597
- const rebasedChangeset = handler.rebaser.rebase(handler.createEmpty(), baseFieldChange.change, (_idNew, idBase) => idBase !== undefined && (0, index_js_1.areEqualChangeAtomIds)(idBase, baseNodeId)
598
- ? baseNodeId
599
- : undefined, idAllocator, new RebaseManager(table, baseFieldChange, rebasedFieldId), metadata);
600
- const rebasedField = { ...baseFieldChange, change: (0, index_js_2.brand)(rebasedChangeset) };
601
- table.rebasedFields.add(rebasedField);
602
- table.baseFieldToContext.set(baseFieldChange, {
603
- newChange: fieldChange,
604
- baseChange: baseFieldChange,
605
- rebasedChange: rebasedField,
606
- fieldId: rebasedFieldId,
607
- baseNodeIds: [],
608
- });
609
- this.attachRebasedField(rebasedFields, rebasedNodes, table, rebasedField, rebasedFieldId, idAllocator, metadata);
692
+ this.rebaseFieldWithoutNewChanges(baseFieldChange, parentFieldIdBase, table, rebasedFields, rebasedNodes, idAllocator, metadata, baseNodeId);
610
693
  }
611
694
  rebaseFieldMap(change, over, parentId, genId, crossFieldTable, revisionMetadata) {
612
695
  const rebasedFields = new Map();
@@ -624,11 +707,11 @@ class ModularChangeFamily {
624
707
  continue;
625
708
  }
626
709
  const { fieldKind, changeHandler, change1: fieldChangeset, change2: baseChangeset, } = this.normalizeFieldChanges(fieldChange, baseChange);
627
- const manager = new RebaseManager(crossFieldTable, baseChange, fieldId);
628
- const rebasedField = changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, manager, revisionMetadata);
710
+ const manager = new RebaseNodeManagerI(crossFieldTable, fieldId);
711
+ const rebasedField = changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, manager, revisionMetadata, crossFieldTable.rebaseVersion);
629
712
  const rebasedFieldChange = {
630
713
  fieldKind,
631
- change: (0, index_js_2.brand)(rebasedField),
714
+ change: (0, index_js_3.brand)(rebasedField),
632
715
  };
633
716
  rebasedFields.set(field, rebasedFieldChange);
634
717
  crossFieldTable.baseFieldToContext.set(baseChange, {
@@ -636,15 +719,15 @@ class ModularChangeFamily {
636
719
  newChange: fieldChange,
637
720
  rebasedChange: rebasedFieldChange,
638
721
  fieldId,
639
- baseNodeIds: [],
722
+ baseNodeIds: (0, index_js_3.newTupleBTree)(),
640
723
  });
641
724
  crossFieldTable.rebasedFields.add(rebasedFieldChange);
642
725
  }
643
726
  return rebasedFields;
644
727
  }
645
728
  rebaseNodeChange(newId, baseId, genId, crossFieldTable, revisionMetadata) {
646
- const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, newId);
647
- const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, baseId);
729
+ const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, crossFieldTable.newChange.nodeAliases, newId);
730
+ const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, crossFieldTable.baseChange.nodeAliases, baseId);
648
731
  const baseMap = over?.fieldChanges ?? new Map();
649
732
  const fieldChanges = change.fieldChanges !== undefined && over.fieldChanges !== undefined
650
733
  ? this.rebaseFieldMap(change?.fieldChanges ?? new Map(), baseMap, newId, genId, crossFieldTable, revisionMetadata)
@@ -659,31 +742,40 @@ class ModularChangeFamily {
659
742
  if (change?.nodeExistsConstraintOnRevert !== undefined) {
660
743
  rebasedChange.nodeExistsConstraintOnRevert = change.nodeExistsConstraintOnRevert;
661
744
  }
662
- setInChangeAtomIdMap(crossFieldTable.baseToRebasedNodeId, baseId, newId);
745
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(crossFieldTable.baseToRebasedNodeId, baseId, newId);
663
746
  return rebasedChange;
664
747
  }
748
+ updateConstraints(rebasedFields, rebasedNodes, rebasedRoots, constraintState, revertConstraintState) {
749
+ this.updateConstraintsForFields(rebasedFields, fieldChangeHandler_js_1.NodeAttachState.Attached, fieldChangeHandler_js_1.NodeAttachState.Attached, constraintState, revertConstraintState, rebasedNodes);
750
+ for (const [_detachId, nodeId] of rebasedRoots.nodeChanges.entries()) {
751
+ // XXX: This is incorrect if the rebased changeset attaches the node.
752
+ // Efficiently computing whether the changeset attaches the node would require maintaining a mapping from node ID to attach ID.
753
+ const detachedInOutput = true;
754
+ this.updateConstraintsForNode(nodeId, fieldChangeHandler_js_1.NodeAttachState.Detached, detachedInOutput ? fieldChangeHandler_js_1.NodeAttachState.Detached : fieldChangeHandler_js_1.NodeAttachState.Attached, rebasedNodes, constraintState, revertConstraintState);
755
+ }
756
+ }
665
757
  updateConstraintsForFields(fields, parentInputAttachState, parentOutputAttachState, constraintState, revertConstraintState, nodes) {
666
758
  for (const field of fields.values()) {
667
759
  const handler = getChangeHandler(this.fieldKinds, field.fieldKind);
668
- for (const [nodeId, inputIndex, outputIndex] of handler.getNestedChanges(field.change)) {
669
- const isInputDetached = inputIndex === undefined;
670
- const inputAttachState = parentInputAttachState === fieldChangeHandler_js_1.NodeAttachState.Detached || isInputDetached
671
- ? fieldChangeHandler_js_1.NodeAttachState.Detached
672
- : fieldChangeHandler_js_1.NodeAttachState.Attached;
673
- const isOutputDetached = outputIndex === undefined;
760
+ for (const [nodeId] of handler.getNestedChanges(field.change)) {
761
+ // XXX: This is incorrect if the rebased changeset detaches this node.
762
+ // Efficiently computing whether the changeset detaches the node would require maintaining a mapping from node ID to detach ID.
763
+ const isOutputDetached = false;
674
764
  const outputAttachState = parentOutputAttachState === fieldChangeHandler_js_1.NodeAttachState.Detached || isOutputDetached
675
765
  ? fieldChangeHandler_js_1.NodeAttachState.Detached
676
766
  : fieldChangeHandler_js_1.NodeAttachState.Attached;
677
- this.updateConstraintsForNode(nodeId, inputAttachState, outputAttachState, nodes, constraintState, revertConstraintState);
767
+ this.updateConstraintsForNode(nodeId, parentInputAttachState, outputAttachState, nodes, constraintState, revertConstraintState);
678
768
  }
679
769
  }
680
770
  }
681
771
  updateConstraintsForNode(nodeId, inputAttachState, outputAttachState, nodes, constraintState, revertConstraintState) {
682
- const node = nodes.get([nodeId.revision, nodeId.localId]) ?? (0, internal_1.fail)(0xb24 /* Unknown node ID */);
772
+ const node = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(nodes, nodeId) ?? (0, internal_1.fail)(0xb24 /* Unknown node ID */);
773
+ const updatedNode = { ...node };
774
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(nodes, nodeId, updatedNode);
683
775
  if (node.nodeExistsConstraint !== undefined) {
684
776
  const isNowViolated = inputAttachState === fieldChangeHandler_js_1.NodeAttachState.Detached;
685
777
  if (node.nodeExistsConstraint.violated !== isNowViolated) {
686
- node.nodeExistsConstraint = {
778
+ updatedNode.nodeExistsConstraint = {
687
779
  ...node.nodeExistsConstraint,
688
780
  violated: isNowViolated,
689
781
  };
@@ -693,7 +785,7 @@ class ModularChangeFamily {
693
785
  if (node.nodeExistsConstraintOnRevert !== undefined) {
694
786
  const isNowViolated = outputAttachState === fieldChangeHandler_js_1.NodeAttachState.Detached;
695
787
  if (node.nodeExistsConstraintOnRevert.violated !== isNowViolated) {
696
- node.nodeExistsConstraintOnRevert = {
788
+ updatedNode.nodeExistsConstraintOnRevert = {
697
789
  ...node.nodeExistsConstraintOnRevert,
698
790
  violated: isNowViolated,
699
791
  };
@@ -704,98 +796,129 @@ class ModularChangeFamily {
704
796
  this.updateConstraintsForFields(node.fieldChanges, inputAttachState, outputAttachState, constraintState, revertConstraintState, nodes);
705
797
  }
706
798
  }
707
- pruneFieldMap(changeset, nodeMap) {
799
+ pruneFieldMap(changeset, parentId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges) {
708
800
  if (changeset === undefined) {
709
801
  return undefined;
710
802
  }
711
803
  const prunedChangeset = new Map();
712
804
  for (const [field, fieldChange] of changeset) {
713
805
  const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
714
- const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) => this.pruneNodeChange(nodeId, nodeMap));
715
- if (!handler.isEmpty(prunedFieldChangeset)) {
716
- prunedChangeset.set(field, { ...fieldChange, change: (0, index_js_2.brand)(prunedFieldChangeset) });
806
+ const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) => this.pruneNodeChange(nodeId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges));
807
+ const fieldId = { nodeId: parentId, field };
808
+ const fieldIdKey = fieldIdKeyFromFieldId(fieldId);
809
+ const rootsWithChanges = fieldsToRootChanges.get(fieldIdKey) ?? [];
810
+ let hasRootWithNodeChange = false;
811
+ for (const rootId of rootsWithChanges) {
812
+ const nodeId = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(roots.nodeChanges, rootId) ?? (0, internal_1.fail)("No root change found");
813
+ const isRootChangeEmpty = this.pruneNodeChange(nodeId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges) === undefined;
814
+ if (isRootChangeEmpty) {
815
+ roots.nodeChanges.delete([rootId.revision, rootId.localId]);
816
+ tryRemoveDetachLocation(roots, rootId, 1);
817
+ }
818
+ else {
819
+ hasRootWithNodeChange = true;
820
+ }
821
+ }
822
+ const hasRootChanges = hasRootWithNodeChange || fieldsWithRootMoves.get(fieldIdKey) === true;
823
+ if (!handler.isEmpty(prunedFieldChangeset) || hasRootChanges) {
824
+ prunedChangeset.set(field, { ...fieldChange, change: (0, index_js_3.brand)(prunedFieldChangeset) });
717
825
  }
718
826
  }
719
827
  return prunedChangeset.size > 0 ? prunedChangeset : undefined;
720
828
  }
721
- pruneNodeChange(nodeId, nodeMap) {
722
- const changeset = nodeChangeFromId(nodeMap, nodeId);
723
- const prunedFields = changeset.fieldChanges !== undefined
724
- ? this.pruneFieldMap(changeset.fieldChanges, nodeMap)
725
- : undefined;
829
+ pruneRoots(roots, nodeMap, nodeToParent, aliases, fieldsWithRootMoves, fieldsToRootChanges) {
830
+ const pruned = { ...roots, nodeChanges: (0, index_js_3.newTupleBTree)() };
831
+ for (const [rootIdKey, nodeId] of roots.nodeChanges.entries()) {
832
+ const rootId = { revision: rootIdKey[0], localId: rootIdKey[1] };
833
+ const hasDetachLocation = roots.detachLocations.getFirst(rootId, 1).value !== undefined;
834
+ // If the root has a detach location it should be pruned by recursion when pruning the field it was detached from.
835
+ const prunedId = hasDetachLocation
836
+ ? nodeId
837
+ : this.pruneNodeChange(nodeId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges);
838
+ if (prunedId !== undefined) {
839
+ pruned.nodeChanges.set(rootIdKey, prunedId);
840
+ }
841
+ tryRemoveDetachLocation(pruned, rootId, 1);
842
+ }
843
+ return pruned;
844
+ }
845
+ pruneNodeChange(nodeId, nodes, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges) {
846
+ const changeset = nodeChangeFromId(nodes, aliases, nodeId);
847
+ const prunedFields = changeset.fieldChanges === undefined
848
+ ? undefined
849
+ : this.pruneFieldMap(changeset.fieldChanges, nodeId, nodes, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges);
726
850
  const prunedChange = { ...changeset, fieldChanges: prunedFields };
727
851
  if (prunedChange.fieldChanges === undefined) {
728
852
  delete prunedChange.fieldChanges;
729
853
  }
730
854
  if (isEmptyNodeChangeset(prunedChange)) {
731
- nodeMap.delete([nodeId.revision, nodeId.localId]);
855
+ const nodeIdKey = [
856
+ nodeId.revision,
857
+ nodeId.localId,
858
+ ];
859
+ // TODO: Shouldn't we also delete all aliases associated with this node?
860
+ nodes.delete(nodeIdKey);
861
+ nodeToParent.delete(nodeIdKey);
732
862
  return undefined;
733
863
  }
734
864
  else {
735
- setInChangeAtomIdMap(nodeMap, nodeId, prunedChange);
865
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(nodes, nodeId, prunedChange);
736
866
  return nodeId;
737
867
  }
738
868
  }
739
- changeRevision(change, newRevision, rollbackOf) {
740
- const oldRevisions = new Set(change.revisions === undefined || change.revisions.length === 0
741
- ? [undefined]
742
- : change.revisions.map((revInfo) => revInfo.revision));
743
- const updatedFields = this.replaceFieldMapRevisions(change.fieldChanges, oldRevisions, newRevision);
744
- const updatedNodes = (0, index_js_2.newTupleBTree)();
745
- for (const [[revision, id], nodeChangeset] of change.nodeChanges.entries()) {
746
- updatedNodes.set([replaceRevision(revision, oldRevisions, newRevision), id], this.replaceNodeChangesetRevisions(nodeChangeset, oldRevisions, newRevision));
869
+ getRevisions(change) {
870
+ if (change.revisions === undefined || change.revisions.length === 0) {
871
+ return new Set([undefined]);
747
872
  }
748
- const updatedNodeToParent = (0, index_js_2.newTupleBTree)();
749
- for (const [[revision, id], fieldId] of change.nodeToParent.entries()) {
750
- updatedNodeToParent.set([replaceRevision(revision, oldRevisions, newRevision), id], replaceFieldIdRevision(normalizeFieldId(fieldId, change.nodeAliases), oldRevisions, newRevision));
873
+ const aggregated = new Set();
874
+ for (const revInfo of change.revisions) {
875
+ aggregated.add(revInfo.revision);
751
876
  }
877
+ return aggregated;
878
+ }
879
+ changeRevision(change, replacer) {
880
+ const updatedFields = this.replaceFieldMapRevisions(change.fieldChanges, replacer);
881
+ const updatedNodes = replaceIdMapRevisions(change.nodeChanges, replacer, (nodeChangeset) => this.replaceNodeChangesetRevisions(nodeChangeset, replacer));
882
+ const updatedNodeToParent = replaceIdMapRevisions(change.nodeToParent, replacer, (location) => replaceNodeLocationRevision(normalizeNodeLocation(location, change.nodeAliases), replacer));
752
883
  const updated = {
753
884
  ...change,
754
885
  fieldChanges: updatedFields,
755
886
  nodeChanges: updatedNodes,
756
887
  nodeToParent: updatedNodeToParent,
888
+ rootNodes: replaceRootTableRevision(change.rootNodes, replacer, change.nodeAliases),
757
889
  // We've updated all references to old node IDs, so we no longer need an alias table.
758
- nodeAliases: (0, index_js_2.newTupleBTree)(),
759
- crossFieldKeys: replaceCrossFieldKeyTableRevisions(change.crossFieldKeys, oldRevisions, newRevision, change.nodeAliases),
890
+ nodeAliases: (0, index_js_3.newTupleBTree)(),
891
+ crossFieldKeys: replaceCrossFieldKeyTableRevisions(change.crossFieldKeys, replacer, change.nodeAliases),
760
892
  };
761
893
  if (change.builds !== undefined) {
762
- updated.builds = replaceIdMapRevisions(change.builds, oldRevisions, newRevision);
894
+ updated.builds = replaceIdMapRevisions(change.builds, replacer);
763
895
  }
764
896
  if (change.destroys !== undefined) {
765
- updated.destroys = replaceIdMapRevisions(change.destroys, oldRevisions, newRevision);
897
+ updated.destroys = replaceIdMapRevisions(change.destroys, replacer);
766
898
  }
767
899
  if (change.refreshers !== undefined) {
768
- updated.refreshers = replaceIdMapRevisions(change.refreshers, oldRevisions, newRevision);
769
- }
770
- if (newRevision !== undefined) {
771
- const revInfo = { revision: newRevision };
772
- if (rollbackOf !== undefined) {
773
- revInfo.rollbackOf = rollbackOf;
774
- }
775
- updated.revisions = [revInfo];
776
- }
777
- else {
778
- delete updated.revisions;
900
+ updated.refreshers = replaceIdMapRevisions(change.refreshers, replacer);
779
901
  }
902
+ updated.revisions = [{ revision: replacer.updatedRevision }];
780
903
  return updated;
781
904
  }
782
- replaceNodeChangesetRevisions(nodeChangeset, oldRevisions, newRevision) {
905
+ replaceNodeChangesetRevisions(nodeChangeset, replacer) {
783
906
  const updated = { ...nodeChangeset };
784
907
  if (nodeChangeset.fieldChanges !== undefined) {
785
- updated.fieldChanges = this.replaceFieldMapRevisions(nodeChangeset.fieldChanges, oldRevisions, newRevision);
908
+ updated.fieldChanges = this.replaceFieldMapRevisions(nodeChangeset.fieldChanges, replacer);
786
909
  }
787
910
  return updated;
788
911
  }
789
- replaceFieldMapRevisions(fields, oldRevisions, newRevision) {
912
+ replaceFieldMapRevisions(fields, replacer) {
790
913
  const updatedFields = new Map();
791
914
  for (const [field, fieldChange] of fields) {
792
- const updatedFieldChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.replaceRevisions(fieldChange.change, oldRevisions, newRevision);
793
- updatedFields.set(field, { ...fieldChange, change: (0, index_js_2.brand)(updatedFieldChange) });
915
+ const updatedFieldChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.replaceRevisions(fieldChange.change, replacer);
916
+ updatedFields.set(field, { ...fieldChange, change: (0, index_js_3.brand)(updatedFieldChange) });
794
917
  }
795
918
  return updatedFields;
796
919
  }
797
920
  makeCrossFieldKeyTable(fields, nodes) {
798
- const keys = (0, modularChangeTypes_js_1.newCrossFieldKeyTable)();
921
+ const keys = (0, modularChangeTypes_js_1.newCrossFieldRangeTable)();
799
922
  this.populateCrossFieldKeyTableForFieldMap(keys, fields, undefined);
800
923
  nodes.forEachPair(([revision, localId], node) => {
801
924
  if (node.fieldChanges !== undefined) {
@@ -815,48 +938,12 @@ class ModularChangeFamily {
815
938
  }
816
939
  }
817
940
  }
818
- buildEditor(changeReceiver) {
819
- return new ModularEditBuilder(this, this.fieldKinds, changeReceiver);
941
+ buildEditor(mintRevisionTag, changeReceiver) {
942
+ return new ModularEditBuilder(this, this.fieldKinds, changeReceiver, this.codecOptions);
820
943
  }
821
944
  createEmptyFieldChange(fieldKind) {
822
945
  const emptyChange = getChangeHandler(this.fieldKinds, fieldKind).createEmpty();
823
- return { fieldKind, change: (0, index_js_2.brand)(emptyChange) };
824
- }
825
- validateChangeset(change) {
826
- let numNodes = this.validateFieldChanges(change, change.fieldChanges, undefined);
827
- for (const [[revision, localId], node] of change.nodeChanges.entries()) {
828
- if (node.fieldChanges === undefined) {
829
- continue;
830
- }
831
- const nodeId = { revision, localId };
832
- const numChildren = this.validateFieldChanges(change, node.fieldChanges, nodeId);
833
- numNodes += numChildren;
834
- }
835
- (0, internal_1.assert)(numNodes === change.nodeChanges.size, 0xa4d /* Node table contains unparented nodes */);
836
- }
837
- /**
838
- * Asserts that each child and cross field key in each field has a correct entry in
839
- * `nodeToParent` or `crossFieldKeyTable`.
840
- * @returns the number of children found.
841
- */
842
- validateFieldChanges(change, fieldChanges, nodeParent) {
843
- let numChildren = 0;
844
- for (const [field, fieldChange] of fieldChanges.entries()) {
845
- const fieldId = { nodeId: nodeParent, field };
846
- const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
847
- for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
848
- const parentFieldId = getParentFieldId(change, child);
849
- (0, internal_1.assert)(areEqualFieldIds(parentFieldId, fieldId), 0xa4e /* Inconsistent node parentage */);
850
- numChildren += 1;
851
- }
852
- for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
853
- const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
854
- (0, internal_1.assert)(fields.length === 1 &&
855
- fields[0] !== undefined &&
856
- areEqualFieldIds(fields[0], fieldId), 0xa4f /* Inconsistent cross field keys */);
857
- }
858
- }
859
- return numChildren;
946
+ return { fieldKind, change: (0, index_js_3.brand)(emptyChange) };
860
947
  }
861
948
  getEffectiveChange(change) {
862
949
  if (hasConflicts(change)) {
@@ -870,9 +957,10 @@ class ModularChangeFamily {
870
957
  muteChange(change) {
871
958
  const muted = {
872
959
  ...change,
873
- crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldKeyTable)(),
960
+ rootNodes: muteRootChanges(change.rootNodes),
961
+ crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldRangeTable)(),
874
962
  fieldChanges: this.muteFieldChanges(change.fieldChanges),
875
- nodeChanges: (0, index_js_2.brand)(change.nodeChanges.mapValues((v) => this.muteNodeChange(v))),
963
+ nodeChanges: (0, index_js_3.brand)(change.nodeChanges.mapValues((v) => this.muteNodeChange(v))),
876
964
  };
877
965
  return muted;
878
966
  }
@@ -892,26 +980,22 @@ class ModularChangeFamily {
892
980
  const handler = getChangeHandler(this.fieldKinds, change.fieldKind);
893
981
  return {
894
982
  fieldKind: change.fieldKind,
895
- change: (0, index_js_2.brand)(handler.rebaser.mute(change.change)),
983
+ change: (0, index_js_3.brand)(handler.rebaser.mute(change.change)),
896
984
  };
897
985
  }
898
986
  }
899
987
  exports.ModularChangeFamily = ModularChangeFamily;
900
988
  ModularChangeFamily.emptyChange = makeModularChangeset();
901
- function replaceCrossFieldKeyTableRevisions(table, oldRevisions, newRevision, nodeAliases) {
902
- const updated = (0, modularChangeTypes_js_1.newCrossFieldKeyTable)();
989
+ function replaceCrossFieldKeyTableRevisions(table, replacer, nodeAliases) {
990
+ const updated = (0, modularChangeTypes_js_1.newCrossFieldRangeTable)();
903
991
  for (const entry of table.entries()) {
904
992
  const key = entry.start;
905
- const updatedKey = {
906
- target: key.target,
907
- revision: replaceRevision(key.revision, oldRevisions, newRevision),
908
- localId: key.localId,
909
- };
993
+ const updatedKey = replacer.getUpdatedAtomId(key);
910
994
  const field = entry.value;
911
995
  const normalizedFieldId = normalizeFieldId(field, nodeAliases);
912
- const updatedNodeId = normalizedFieldId.nodeId !== undefined
913
- ? (0, index_js_1.replaceAtomRevisions)(normalizedFieldId.nodeId, oldRevisions, newRevision)
914
- : undefined;
996
+ const updatedNodeId = normalizedFieldId.nodeId === undefined
997
+ ? undefined
998
+ : replacer.getUpdatedAtomId(normalizedFieldId.nodeId);
915
999
  const updatedValue = {
916
1000
  ...normalizedFieldId,
917
1001
  nodeId: updatedNodeId,
@@ -920,13 +1004,11 @@ function replaceCrossFieldKeyTableRevisions(table, oldRevisions, newRevision, no
920
1004
  }
921
1005
  return updated;
922
1006
  }
923
- function replaceRevision(revision, oldRevisions, newRevision) {
924
- return oldRevisions.has(revision) ? newRevision : revision;
925
- }
926
- function replaceIdMapRevisions(map, oldRevisions, newRevision) {
927
- const updated = (0, index_js_2.newTupleBTree)();
928
- for (const [[revision, id], value] of map.entries()) {
929
- updated.set([replaceRevision(revision, oldRevisions, newRevision), id], value);
1007
+ function replaceIdMapRevisions(map, replacer, valueMapper = (value) => value) {
1008
+ const updated = (0, index_js_3.newTupleBTree)();
1009
+ for (const [[revision, localId], value] of map.entries()) {
1010
+ const newAtom = replacer.getUpdatedAtomId({ revision, localId });
1011
+ updated.set([newAtom.revision, newAtom.localId], valueMapper(value));
930
1012
  }
931
1013
  return updated;
932
1014
  }
@@ -941,9 +1023,9 @@ function composeBuildsDestroysAndRefreshers(change1, change2) {
941
1023
  // Note that it would in principle be possible to adopt the later build and exclude from the
942
1024
  // composition all the changes already reflected on the tree, but that is not something we
943
1025
  // care to support at this time.
944
- const allBuilds = (0, index_js_2.brand)((0, index_js_2.mergeTupleBTrees)(change1.builds ?? (0, index_js_2.newTupleBTree)(), change2.builds ?? (0, index_js_2.newTupleBTree)(), true));
945
- const allDestroys = (0, index_js_2.brand)((0, index_js_2.mergeTupleBTrees)(change1.destroys ?? (0, index_js_2.newTupleBTree)(), change2.destroys ?? (0, index_js_2.newTupleBTree)()));
946
- const allRefreshers = (0, index_js_2.brand)((0, index_js_2.mergeTupleBTrees)(change1.refreshers ?? (0, index_js_2.newTupleBTree)(), change2.refreshers ?? (0, index_js_2.newTupleBTree)(), true));
1026
+ const allBuilds = (0, index_js_3.brand)((0, index_js_3.mergeTupleBTrees)(change1.builds ?? (0, index_js_3.newTupleBTree)(), change2.builds ?? (0, index_js_3.newTupleBTree)(), true));
1027
+ const allDestroys = (0, index_js_3.brand)((0, index_js_3.mergeTupleBTrees)(change1.destroys ?? (0, index_js_3.newTupleBTree)(), change2.destroys ?? (0, index_js_3.newTupleBTree)()));
1028
+ const allRefreshers = (0, index_js_3.brand)((0, index_js_3.mergeTupleBTrees)(change1.refreshers ?? (0, index_js_3.newTupleBTree)(), change2.refreshers ?? (0, index_js_3.newTupleBTree)(), true));
947
1029
  if (change1.destroys !== undefined && change2.builds !== undefined) {
948
1030
  for (const [key, chunk] of change2.builds.entries()) {
949
1031
  const destroyCount = change1.destroys.get(key);
@@ -964,11 +1046,24 @@ function composeBuildsDestroysAndRefreshers(change1, change2) {
964
1046
  }
965
1047
  }
966
1048
  }
1049
+ // It's possible to have a build and a refresher for the same root because an attach operation need not be performed in the same changeset as the corresponding build.
1050
+ if (change1.builds !== undefined && change2.refreshers !== undefined) {
1051
+ for (const [key, chunk] of change2.refreshers.entries()) {
1052
+ (0, internal_1.assert)(chunk.topLevelLength === 1, "Expected refresher chunk to have length 1");
1053
+ const match = change1.builds.getPairOrNextLower(key);
1054
+ if (match !== undefined) {
1055
+ const [buildKey, buildChunk] = match;
1056
+ if (buildKey[0] === key[0] && buildKey[1] + buildChunk.topLevelLength > key[1]) {
1057
+ allRefreshers.delete(key);
1058
+ }
1059
+ }
1060
+ }
1061
+ }
967
1062
  return { allBuilds, allDestroys, allRefreshers };
968
1063
  }
969
1064
  function invertBuilds(builds) {
970
1065
  if (builds !== undefined) {
971
- return (0, index_js_2.brand)(builds.mapValues((chunk) => chunk.topLevelLength));
1066
+ return (0, index_js_3.brand)(builds.mapValues((chunk) => chunk.topLevelLength));
972
1067
  }
973
1068
  return undefined;
974
1069
  }
@@ -988,19 +1083,53 @@ function invertBuilds(builds) {
988
1083
  * @param fieldKinds - The field kinds to delegate to.
989
1084
  */
990
1085
  function* relevantRemovedRoots(change, fieldKinds) {
991
- yield* relevantRemovedRootsFromFields(change.fieldChanges, change.nodeChanges, fieldKinds);
1086
+ const rootIds = (0, index_js_2.newChangeAtomIdRangeMap)();
1087
+ addAttachesToSet(change, rootIds);
1088
+ addRenamesToSet(change, rootIds);
1089
+ for (const [[revision, localId]] of change.rootNodes.nodeChanges.entries()) {
1090
+ rootIds.set({ revision, localId }, 1, true);
1091
+ }
1092
+ for (const entry of rootIds.entries()) {
1093
+ for (let offset = 0; offset < entry.length; offset++) {
1094
+ const detachId = (0, index_js_2.offsetChangeAtomId)(entry.start, offset);
1095
+ yield (0, index_js_2.makeDetachedNodeId)(detachId.revision, detachId.localId);
1096
+ }
1097
+ }
992
1098
  }
993
1099
  exports.relevantRemovedRoots = relevantRemovedRoots;
994
- function* relevantRemovedRootsFromFields(change, nodeChanges, fieldKinds) {
995
- for (const [_, fieldChange] of change) {
996
- const handler = getChangeHandler(fieldKinds, fieldChange.fieldKind);
997
- const delegate = function* (node) {
998
- const nodeChangeset = nodeChangeFromId(nodeChanges, node);
999
- if (nodeChangeset.fieldChanges !== undefined) {
1000
- yield* relevantRemovedRootsFromFields(nodeChangeset.fieldChanges, nodeChanges, fieldKinds);
1100
+ function* getBuildIds(change) {
1101
+ if (change.builds !== undefined) {
1102
+ for (const [[revision, localId]] of change.builds.entries()) {
1103
+ yield (0, index_js_2.makeDetachedNodeId)(revision, localId);
1104
+ }
1105
+ }
1106
+ }
1107
+ exports.getBuildIds = getBuildIds;
1108
+ function addAttachesToSet(change, rootIds) {
1109
+ // This includes each attach which does not have a corresponding detach.
1110
+ for (const entry of change.crossFieldKeys.entries()) {
1111
+ if (entry.start.target !== crossFieldQueries_js_1.CrossFieldTarget.Destination) {
1112
+ continue;
1113
+ }
1114
+ for (const detachIdEntry of change.rootNodes.newToOldId.getAll2(entry.start, entry.length)) {
1115
+ const detachId = detachIdEntry.value ?? (0, index_js_2.offsetChangeAtomId)(entry.start, detachIdEntry.offset);
1116
+ for (const detachEntry of change.crossFieldKeys.getAll2({ ...detachId, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, detachIdEntry.length)) {
1117
+ if (detachEntry.value === undefined) {
1118
+ rootIds.set((0, index_js_2.offsetChangeAtomId)(detachId, detachEntry.offset), detachEntry.length, true);
1119
+ }
1001
1120
  }
1002
- };
1003
- yield* handler.relevantRemovedRoots(fieldChange.change, delegate);
1121
+ }
1122
+ }
1123
+ }
1124
+ function addRenamesToSet(change, rootIds) {
1125
+ for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
1126
+ for (const detachEntry of change.crossFieldKeys.getAll2({ ...renameEntry.start, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, renameEntry.length)) {
1127
+ // We only want to include renames of nodes which are detached in the input context of the changeset.
1128
+ // So if there is a detach for the node, the rename is not relevant.
1129
+ if (detachEntry.value === undefined) {
1130
+ rootIds.set(renameEntry.start, renameEntry.length, true);
1131
+ }
1132
+ }
1004
1133
  }
1005
1134
  }
1006
1135
  /**
@@ -1015,11 +1144,11 @@ function* relevantRemovedRootsFromFields(change, nodeChanges, fieldKinds) {
1015
1144
  * corresponding build or refresher.
1016
1145
  */
1017
1146
  function updateRefreshers(change, getDetachedNode, removedRoots, requireRefreshers = true) {
1018
- const refreshers = (0, index_js_2.newTupleBTree)();
1147
+ const refreshers = (0, index_js_3.newTupleBTree)();
1019
1148
  const chunkLengths = new Map();
1020
1149
  if (change.builds !== undefined) {
1021
1150
  for (const [[revision, id], chunk] of change.builds.entries()) {
1022
- const lengthTree = (0, index_js_2.getOrCreate)(chunkLengths, revision, () => new sorted_btree_es6_1.BTree());
1151
+ const lengthTree = (0, index_js_3.getOrCreate)(chunkLengths, revision, () => new sorted_btree_es6_1.BTree());
1023
1152
  lengthTree.set(id, chunk.topLevelLength);
1024
1153
  }
1025
1154
  }
@@ -1043,16 +1172,17 @@ function updateRefreshers(change, getDetachedNode, removedRoots, requireRefreshe
1043
1172
  (0, internal_1.assert)(!requireRefreshers, 0x8cd /* detached node should exist */);
1044
1173
  }
1045
1174
  else {
1046
- refreshers.set([root.major, (0, index_js_2.brand)(root.minor)], node);
1175
+ refreshers.set([root.major, (0, index_js_3.brand)(root.minor)], node);
1047
1176
  }
1048
1177
  }
1049
- const { fieldChanges, nodeChanges, maxId, revisions, constraintViolationCount, constraintViolationCountOnRevert, builds, destroys, } = change;
1178
+ const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys, maxId, revisions, constraintViolationCount, constraintViolationCountOnRevert, builds, destroys, rootNodes, } = change;
1050
1179
  return makeModularChangeset({
1051
1180
  fieldChanges,
1052
1181
  nodeChanges,
1053
- nodeToParent: change.nodeToParent,
1054
- nodeAliases: change.nodeAliases,
1055
- crossFieldKeys: change.crossFieldKeys,
1182
+ nodeToParent,
1183
+ nodeAliases,
1184
+ crossFieldKeys,
1185
+ rootNodes,
1056
1186
  maxId: maxId,
1057
1187
  revisions,
1058
1188
  constraintViolationCount,
@@ -1072,11 +1202,24 @@ exports.updateRefreshers = updateRefreshers;
1072
1202
  function intoDelta(taggedChange, fieldKinds) {
1073
1203
  const change = taggedChange.change;
1074
1204
  const rootDelta = {};
1075
- const global = [];
1076
- const rename = [];
1077
1205
  if (!hasConflicts(change)) {
1078
1206
  // If there are no constraint violations, then tree changes apply.
1079
- const fieldDeltas = intoDeltaImpl(change.fieldChanges, change.nodeChanges, fieldKinds, global, rename);
1207
+ const fieldDeltas = intoDeltaImpl(change.fieldChanges, change.nodeChanges, change.nodeAliases, fieldKinds);
1208
+ const global = [];
1209
+ for (const [[major, minor], nodeId] of change.rootNodes.nodeChanges.entries()) {
1210
+ global.push({
1211
+ id: { major, minor },
1212
+ fields: deltaFromNodeChange(nodeChangeFromId(change.nodeChanges, change.nodeAliases, nodeId), change.nodeChanges, change.nodeAliases, fieldKinds),
1213
+ });
1214
+ }
1215
+ const rename = [];
1216
+ for (const { start: oldId, value: newId, length, } of change.rootNodes.oldToNewId.entries()) {
1217
+ rename.push({
1218
+ count: length,
1219
+ oldId: (0, index_js_2.makeDetachedNodeId)(oldId.revision, oldId.localId),
1220
+ newId: (0, index_js_2.makeDetachedNodeId)(newId.revision, newId.localId),
1221
+ });
1222
+ }
1080
1223
  if (fieldDeltas.size > 0) {
1081
1224
  rootDelta.fields = fieldDeltas;
1082
1225
  }
@@ -1095,7 +1238,7 @@ function intoDelta(taggedChange, fieldKinds) {
1095
1238
  const destroys = [];
1096
1239
  for (const [[major, minor], count] of change.destroys.entries()) {
1097
1240
  destroys.push({
1098
- id: (0, index_js_1.makeDetachedNodeId)(major, minor),
1241
+ id: (0, index_js_2.makeDetachedNodeId)(major, minor),
1099
1242
  count,
1100
1243
  });
1101
1244
  }
@@ -1113,7 +1256,7 @@ function copyDetachedNodes(detachedNodes) {
1113
1256
  if (chunk.topLevelLength > 0) {
1114
1257
  chunk.referenceAdded();
1115
1258
  copiedDetachedNodes.push({
1116
- id: (0, index_js_1.makeDetachedNodeId)(major, minor),
1259
+ id: (0, index_js_2.makeDetachedNodeId)(major, minor),
1117
1260
  trees: chunk,
1118
1261
  });
1119
1262
  }
@@ -1123,24 +1266,22 @@ function copyDetachedNodes(detachedNodes) {
1123
1266
  /**
1124
1267
  * @param change - The change to convert into a delta.
1125
1268
  */
1126
- function intoDeltaImpl(change, nodeChanges, fieldKinds, global, rename) {
1269
+ function intoDeltaImpl(change, nodeChanges, nodeAliases, fieldKinds) {
1127
1270
  const delta = new Map();
1128
1271
  for (const [field, fieldChange] of change) {
1129
- const { local: fieldChanges, global: fieldGlobal, rename: fieldRename, } = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(fieldChange.change, (childChange) => {
1130
- const nodeChange = nodeChangeFromId(nodeChanges, childChange);
1131
- return deltaFromNodeChange(nodeChange, nodeChanges, fieldKinds, global, rename);
1272
+ const fieldDelta = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(fieldChange.change, (childChange) => {
1273
+ const nodeChange = nodeChangeFromId(nodeChanges, nodeAliases, childChange);
1274
+ return deltaFromNodeChange(nodeChange, nodeChanges, nodeAliases, fieldKinds);
1132
1275
  });
1133
- if (fieldChanges !== undefined && fieldChanges.length > 0) {
1134
- delta.set(field, fieldChanges);
1276
+ if (fieldDelta !== undefined && fieldDelta.length > 0) {
1277
+ delta.set(field, fieldDelta);
1135
1278
  }
1136
- fieldGlobal?.forEach((c) => global.push(c));
1137
- fieldRename?.forEach((r) => rename.push(r));
1138
1279
  }
1139
1280
  return delta;
1140
1281
  }
1141
- function deltaFromNodeChange(change, nodeChanges, fieldKinds, global, rename) {
1282
+ function deltaFromNodeChange(change, nodeChanges, nodeAliases, fieldKinds) {
1142
1283
  if (change.fieldChanges !== undefined) {
1143
- return intoDeltaImpl(change.fieldChanges, nodeChanges, fieldKinds, global, rename);
1284
+ return intoDeltaImpl(change.fieldChanges, nodeChanges, nodeAliases, fieldKinds);
1144
1285
  }
1145
1286
  // TODO: update the API to allow undefined to be returned here
1146
1287
  return new Map();
@@ -1166,7 +1307,7 @@ function rebaseRevisionMetadataFromInfo(revInfos, revisionToRebase, baseRevision
1166
1307
  }
1167
1308
  const getBaseRevisions = () => filteredRevisions;
1168
1309
  return {
1169
- ...(0, index_js_1.revisionMetadataSourceFromInfo)(revInfos),
1310
+ ...(0, index_js_2.revisionMetadataSourceFromInfo)(revInfos),
1170
1311
  getRevisionToRebase: () => revisionToRebase,
1171
1312
  getBaseRevisions,
1172
1313
  };
@@ -1190,30 +1331,22 @@ function getChangeHandler(fieldKinds, kind) {
1190
1331
  return getFieldKind(fieldKinds, kind).changeHandler;
1191
1332
  }
1192
1333
  exports.getChangeHandler = getChangeHandler;
1193
- function newComposeTable(baseChange, newChange, composedNodeToParent) {
1334
+ function newComposeTable(baseChange, newChange, composedRootNodes, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions) {
1194
1335
  return {
1195
- ...newCrossFieldTable(),
1336
+ rebaseVersion: Math.max(baseChange.rebaseVersion, newChange.rebaseVersion),
1337
+ entries: newDetachedEntryMap(),
1196
1338
  baseChange,
1197
1339
  newChange,
1198
1340
  fieldToContext: new Map(),
1199
1341
  newFieldToBaseField: new Map(),
1200
- newToBaseNodeId: (0, index_js_2.newTupleBTree)(),
1342
+ newToBaseNodeId: (0, index_js_3.newTupleBTree)(),
1201
1343
  composedNodes: new Set(),
1202
- composedNodeToParent,
1203
- pendingCompositions: {
1204
- nodeIdsToCompose: [],
1205
- affectedBaseFields: (0, index_js_2.newTupleBTree)(),
1206
- affectedNewFields: (0, index_js_2.newTupleBTree)(),
1207
- },
1208
- };
1209
- }
1210
- function newCrossFieldTable() {
1211
- return {
1212
- srcTable: (0, index_js_1.newChangeAtomIdRangeMap)(),
1213
- dstTable: (0, index_js_1.newChangeAtomIdRangeMap)(),
1214
- srcDependents: (0, index_js_1.newChangeAtomIdRangeMap)(),
1215
- dstDependents: (0, index_js_1.newChangeAtomIdRangeMap)(),
1216
- invalidatedFields: new Set(),
1344
+ movedNodeToParent: (0, index_js_3.newTupleBTree)(),
1345
+ composedRootNodes,
1346
+ movedCrossFieldKeys,
1347
+ removedCrossFieldKeys,
1348
+ renamesToDelete: (0, index_js_2.newChangeAtomIdRangeMap)(),
1349
+ pendingCompositions,
1217
1350
  };
1218
1351
  }
1219
1352
  function newConstraintState(violationCount) {
@@ -1221,190 +1354,406 @@ function newConstraintState(violationCount) {
1221
1354
  violationCount,
1222
1355
  };
1223
1356
  }
1224
- class CrossFieldManagerI {
1225
- constructor(crossFieldTable, currentFieldKey, allowInval = true) {
1226
- this.crossFieldTable = crossFieldTable;
1227
- this.currentFieldKey = currentFieldKey;
1228
- this.allowInval = allowInval;
1357
+ class InvertNodeManagerI {
1358
+ constructor(table, fieldId) {
1359
+ this.table = table;
1360
+ this.fieldId = fieldId;
1229
1361
  }
1230
- set(target, revision, id, count, newValue, invalidateDependents) {
1231
- if (invalidateDependents && this.allowInval) {
1232
- const lastChangedId = id + count - 1;
1233
- let firstId = id;
1234
- while (firstId <= lastChangedId) {
1235
- const dependentEntry = (0, crossFieldQueries_js_1.getFirstFromCrossFieldMap)(this.getDependents(target), revision, firstId, lastChangedId - firstId + 1);
1236
- if (dependentEntry.value !== undefined) {
1237
- this.crossFieldTable.invalidatedFields.add(dependentEntry.value);
1362
+ invertDetach(detachId, count, nodeChange, newAttachId) {
1363
+ if (nodeChange !== undefined) {
1364
+ (0, internal_1.assert)(count === 1, "A node change should only affect one node");
1365
+ const attachEntry = firstAttachIdFromDetachId(this.table.change.rootNodes, detachId, count);
1366
+ const attachFieldEntry = this.table.change.crossFieldKeys.getFirst({ target: crossFieldQueries_js_1.CrossFieldTarget.Destination, ...attachEntry.value }, count);
1367
+ if (attachFieldEntry.value === undefined) {
1368
+ assignRootChange(this.table.invertedRoots, this.table.invertedNodeToParent, attachEntry.value, nodeChange, this.fieldId, this.table.change.rebaseVersion);
1369
+ }
1370
+ else {
1371
+ (0, crossFieldQueries_js_1.setInCrossFieldMap)(this.table.entries, attachEntry.value, count, nodeChange);
1372
+ this.table.invalidatedFields.add(fieldChangeFromId(this.table.change, attachFieldEntry.value));
1373
+ }
1374
+ }
1375
+ if (!(0, index_js_2.areEqualChangeAtomIds)(detachId, newAttachId)) {
1376
+ for (const entry of doesChangeAttachNodes(this.table.change.crossFieldKeys, detachId, count)) {
1377
+ if (!entry.value) {
1378
+ this.table.attachToDetachId.set(newAttachId, count, detachId);
1379
+ this.table.invertedRoots.detachLocations.set(detachId, count, this.fieldId);
1238
1380
  }
1239
- firstId = (0, index_js_2.brand)(firstId + dependentEntry.length);
1240
1381
  }
1241
1382
  }
1242
- (0, crossFieldQueries_js_1.setInCrossFieldMap)(this.getMap(target), revision, id, count, newValue);
1243
1383
  }
1244
- get(target, revision, id, count, addDependency) {
1245
- if (addDependency) {
1246
- // We assume that if there is already an entry for this ID it is because
1247
- // a field handler has called compose on the same node multiple times.
1248
- // In this case we only want to update the latest version, so we overwrite the dependency.
1249
- (0, crossFieldQueries_js_1.setInCrossFieldMap)(this.getDependents(target), revision, id, count, this.currentFieldKey);
1384
+ invertAttach(attachId, count) {
1385
+ let countToProcess = count;
1386
+ const detachIdEntry = firstDetachIdFromAttachId(this.table.change.rootNodes, attachId, countToProcess);
1387
+ countToProcess = detachIdEntry.length;
1388
+ const detachEntry = getFirstFieldForCrossFieldKey(this.table.change, { target: crossFieldQueries_js_1.CrossFieldTarget.Source, ...detachIdEntry.value }, countToProcess);
1389
+ countToProcess = detachEntry.length;
1390
+ let result;
1391
+ if (detachEntry.value === undefined) {
1392
+ // This node is detached in the input context of the original change.
1393
+ const nodeIdEntry = (0, changeAtomIdBTree_js_1.rangeQueryChangeAtomIdMap)(this.table.change.rootNodes.nodeChanges, detachIdEntry.value, countToProcess);
1394
+ countToProcess = nodeIdEntry.length;
1395
+ result = {
1396
+ value: { nodeChange: nodeIdEntry.value, detachId: detachIdEntry.value },
1397
+ length: countToProcess,
1398
+ };
1250
1399
  }
1251
- return (0, crossFieldQueries_js_1.getFirstFromCrossFieldMap)(this.getMap(target), revision, id, count);
1252
- }
1253
- getMap(target) {
1254
- return target === crossFieldQueries_js_1.CrossFieldTarget.Source
1255
- ? this.crossFieldTable.srcTable
1256
- : this.crossFieldTable.dstTable;
1257
- }
1258
- getDependents(target) {
1259
- return target === crossFieldQueries_js_1.CrossFieldTarget.Source
1260
- ? this.crossFieldTable.srcDependents
1261
- : this.crossFieldTable.dstDependents;
1262
- }
1263
- }
1264
- class InvertManager extends CrossFieldManagerI {
1265
- constructor(table, field, fieldId, allowInval = true) {
1266
- super(table, field, allowInval);
1267
- this.fieldId = fieldId;
1268
- }
1269
- onMoveIn(id) {
1270
- setInChangeAtomIdMap(this.table.invertedNodeToParent, id, this.fieldId);
1271
- }
1272
- moveKey(target, revision, id, count) {
1273
- (0, internal_1.assert)(false, 0x9c5 /* Keys should not be moved manually during invert */);
1274
- }
1275
- get table() {
1276
- return this.crossFieldTable;
1400
+ else {
1401
+ const moveEntry = this.table.entries.getFirst(attachId, countToProcess);
1402
+ result = { ...moveEntry, value: { nodeChange: moveEntry.value } };
1403
+ }
1404
+ if (result.value?.nodeChange !== undefined) {
1405
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(this.table.invertedNodeToParent, result.value.nodeChange, {
1406
+ field: this.fieldId,
1407
+ });
1408
+ }
1409
+ return result;
1277
1410
  }
1278
1411
  }
1279
- class RebaseManager extends CrossFieldManagerI {
1280
- constructor(table, currentField, fieldId, allowInval = true) {
1281
- super(table, currentField, allowInval);
1412
+ class RebaseNodeManagerI {
1413
+ constructor(table, fieldId, allowInval = true) {
1414
+ this.table = table;
1282
1415
  this.fieldId = fieldId;
1416
+ this.allowInval = allowInval;
1283
1417
  }
1284
- set(target, revision, id, count, newValue, invalidateDependents) {
1285
- if (invalidateDependents && this.allowInval) {
1286
- const newFieldIds = getFieldsForCrossFieldKey(this.table.newChange, {
1287
- target,
1288
- revision,
1289
- localId: id,
1290
- }, count);
1291
- (0, internal_1.assert)(newFieldIds.length === 0, 0x9c6 /* TODO: Modifying a cross-field key from the new changeset is currently unsupported */);
1292
- const baseFieldIds = getFieldsForCrossFieldKey(this.table.baseChange, {
1293
- target,
1294
- revision,
1295
- localId: id,
1296
- }, count);
1297
- (0, internal_1.assert)(baseFieldIds.length > 0, 0x9c7 /* Cross field key not registered in base or new change */);
1298
- for (const baseFieldId of baseFieldIds) {
1299
- this.table.affectedBaseFields.set([baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field], true);
1418
+ getNewChangesForBaseAttach(baseAttachId, count) {
1419
+ let countToProcess = count;
1420
+ const detachEntry = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseAttachId, countToProcess);
1421
+ countToProcess = detachEntry.length;
1422
+ const nodeEntry = (0, changeAtomIdBTree_js_1.rangeQueryChangeAtomIdMap)(this.table.newChange.rootNodes.nodeChanges, detachEntry.value, countToProcess);
1423
+ countToProcess = nodeEntry.length;
1424
+ const newNodeId = nodeEntry.value;
1425
+ const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(detachEntry.value, countToProcess);
1426
+ countToProcess = newRenameEntry.length;
1427
+ let result;
1428
+ // eslint-disable-next-line unicorn/prefer-ternary
1429
+ if (newNodeId !== undefined || newRenameEntry.value !== undefined) {
1430
+ result = {
1431
+ ...newRenameEntry,
1432
+ value: { detachId: newRenameEntry.value, nodeChange: newNodeId },
1433
+ };
1434
+ }
1435
+ else {
1436
+ // This handles the case where the base changeset has moved these nodes,
1437
+ // meaning they were attached in the input context of the base changeset.
1438
+ result = this.table.entries.getFirst(baseAttachId, countToProcess);
1439
+ }
1440
+ // TODO: Consider moving these two checks into a separate method so that this function has no side effects.
1441
+ if (result.value?.detachId !== undefined) {
1442
+ this.table.rebasedDetachLocations.set(result.value.detachId, result.length, this.fieldId);
1443
+ }
1444
+ if (result.value?.nodeChange !== undefined) {
1445
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(this.table.rebasedNodeToParent, result.value.nodeChange, {
1446
+ field: this.fieldId,
1447
+ });
1448
+ }
1449
+ return result;
1450
+ }
1451
+ rebaseOverDetach(baseDetachId, count, newDetachId, nodeChange, cellRename) {
1452
+ let countToProcess = count;
1453
+ const attachIdEntry = firstAttachIdFromDetachId(this.table.baseRoots, baseDetachId, countToProcess);
1454
+ const baseAttachId = attachIdEntry.value;
1455
+ countToProcess = attachIdEntry.length;
1456
+ const attachFieldEntry = getFirstFieldForCrossFieldKey(this.table.baseChange, { ...baseAttachId, target: crossFieldQueries_js_1.CrossFieldTarget.Destination }, countToProcess);
1457
+ countToProcess = attachFieldEntry.length;
1458
+ const detachedMoveEntry = this.table.baseChange.rootNodes.outputDetachLocations.getFirst(baseDetachId, countToProcess);
1459
+ countToProcess = detachedMoveEntry.length;
1460
+ const destinationField = attachFieldEntry.value ?? detachedMoveEntry.value;
1461
+ if (destinationField !== undefined) {
1462
+ // The base detach is part of a move (or move of detach location) in the base changeset.
1463
+ (0, crossFieldQueries_js_1.setInCrossFieldMap)(this.table.entries, baseAttachId, countToProcess, {
1464
+ nodeChange,
1465
+ detachId: newDetachId,
1466
+ cellRename,
1467
+ });
1468
+ if (nodeChange !== undefined || newDetachId !== undefined) {
1469
+ this.invalidateBaseFields([destinationField]);
1470
+ }
1471
+ }
1472
+ if (attachFieldEntry.value === undefined) {
1473
+ // These nodes are detached in the output context of the base changeset.
1474
+ if (nodeChange !== undefined) {
1475
+ assignRootChange(this.table.rebasedRootNodes, this.table.rebasedNodeToParent, baseAttachId, nodeChange, this.fieldId, this.table.rebaseVersion);
1476
+ }
1477
+ if (newDetachId !== undefined) {
1478
+ addNodeRename(this.table.rebasedRootNodes, baseAttachId, newDetachId, countToProcess, this.fieldId);
1479
+ }
1480
+ }
1481
+ if (newDetachId !== undefined) {
1482
+ this.table.movedDetaches.set(newDetachId, countToProcess, true);
1483
+ }
1484
+ if (countToProcess < count) {
1485
+ const remainingCount = count - countToProcess;
1486
+ const nextDetachId = newDetachId === undefined
1487
+ ? undefined
1488
+ : (0, index_js_2.offsetChangeAtomId)(newDetachId, countToProcess);
1489
+ this.rebaseOverDetach((0, index_js_2.offsetChangeAtomId)(baseDetachId, countToProcess), remainingCount, nextDetachId, nodeChange);
1490
+ }
1491
+ }
1492
+ addDetach(id, count) {
1493
+ this.table.rebasedDetachLocations.set(id, count, this.fieldId);
1494
+ }
1495
+ removeDetach(id, count) {
1496
+ this.table.movedDetaches.set(id, count, true);
1497
+ }
1498
+ doesBaseAttachNodes(id, count) {
1499
+ let countToProcess = count;
1500
+ const attachEntry = getFirstAttachField(this.table.baseChange.crossFieldKeys, id, countToProcess);
1501
+ countToProcess = attachEntry.length;
1502
+ return { start: id, value: attachEntry.value !== undefined, length: countToProcess };
1503
+ }
1504
+ getBaseRename(id, count) {
1505
+ return this.table.baseChange.rootNodes.oldToNewId.getFirst(id, count);
1506
+ }
1507
+ getNewRenameForBaseRename(baseRenameTo, count) {
1508
+ let countToProcess = count;
1509
+ const inputEntry = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseRenameTo, countToProcess);
1510
+ const attachEntry = getFirstAttachField(this.table.baseChange.crossFieldKeys, baseRenameTo, countToProcess);
1511
+ countToProcess = attachEntry.length;
1512
+ if (attachEntry.value !== undefined) {
1513
+ // These nodes are attached in the output context of the base changeset.
1514
+ return { value: undefined, length: countToProcess };
1515
+ }
1516
+ countToProcess = inputEntry.length;
1517
+ const inputId = inputEntry.value;
1518
+ const moveEntry = this.table.entries.getFirst(inputId, countToProcess);
1519
+ countToProcess = moveEntry.length;
1520
+ if (moveEntry.value !== undefined) {
1521
+ return { ...moveEntry, value: moveEntry.value.cellRename ?? moveEntry.value.detachId };
1522
+ }
1523
+ return this.table.newChange.rootNodes.oldToNewId.getFirst(inputId, countToProcess);
1524
+ }
1525
+ invalidateBaseFields(fields) {
1526
+ if (this.allowInval) {
1527
+ for (const fieldId of fields) {
1528
+ this.table.affectedBaseFields.set(fieldIdKeyFromFieldId(fieldId), true);
1300
1529
  }
1301
1530
  }
1302
- super.set(target, revision, id, count, newValue, invalidateDependents);
1303
- }
1304
- onMoveIn(id) {
1305
- setInChangeAtomIdMap(this.table.rebasedNodeToParent, id, this.fieldId);
1306
- }
1307
- moveKey(target, revision, id, count) {
1308
- this.table.rebasedCrossFieldKeys.set({ target, revision, localId: id }, count, this.fieldId);
1309
1531
  }
1310
- get table() {
1311
- return this.crossFieldTable;
1532
+ }
1533
+ function assignRootChange(table, nodeToParent, detachId, nodeId, detachLocation, rebaseVersion) {
1534
+ (0, internal_1.assert)(rebaseVersion >= 2 || detachLocation !== undefined, "All root changes need a detach location to support compatibility with older client versions");
1535
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(table.nodeChanges, detachId, nodeId);
1536
+ if (nodeToParent !== undefined) {
1537
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(nodeToParent, nodeId, { root: detachId });
1312
1538
  }
1539
+ table.detachLocations.set(detachId, 1, detachLocation);
1313
1540
  }
1314
- // TODO: Deduplicate this with RebaseTable
1315
- class ComposeManager extends CrossFieldManagerI {
1316
- constructor(table, currentField, fieldId, allowInval = true) {
1317
- super(table, currentField, allowInval);
1541
+ class ComposeNodeManagerI {
1542
+ constructor(table, fieldId, allowInval = true) {
1543
+ this.table = table;
1318
1544
  this.fieldId = fieldId;
1545
+ this.allowInval = allowInval;
1319
1546
  }
1320
- set(target, revision, id, count, newValue, invalidateDependents) {
1321
- if (invalidateDependents && this.allowInval) {
1322
- const newFieldIds = getFieldsForCrossFieldKey(this.table.newChange, {
1323
- target,
1324
- revision,
1325
- localId: id,
1326
- }, count);
1327
- if (newFieldIds.length > 0) {
1328
- for (const newFieldId of newFieldIds) {
1329
- this.table.pendingCompositions.affectedNewFields.set([newFieldId.nodeId?.revision, newFieldId.nodeId?.localId, newFieldId.field], true);
1330
- }
1547
+ getNewChangesForBaseDetach(baseDetachId, count) {
1548
+ let countToProcess = count;
1549
+ const baseAttachEntry = getFirstFieldForCrossFieldKey(this.table.baseChange, { target: crossFieldQueries_js_1.CrossFieldTarget.Destination, ...baseDetachId }, countToProcess);
1550
+ countToProcess = baseAttachEntry.length;
1551
+ let result;
1552
+ if (baseAttachEntry.value === undefined) {
1553
+ // The detached nodes are still detached in the new change's input context.
1554
+ const rootEntry = (0, changeAtomIdBTree_js_1.rangeQueryChangeAtomIdMap)(this.table.newChange.rootNodes.nodeChanges, baseDetachId, countToProcess);
1555
+ countToProcess = rootEntry.length;
1556
+ const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(baseDetachId, countToProcess);
1557
+ countToProcess = newRenameEntry.length;
1558
+ result = {
1559
+ value: { nodeChange: rootEntry.value, detachId: newRenameEntry.value },
1560
+ length: countToProcess,
1561
+ };
1562
+ }
1563
+ else {
1564
+ // The base detach was part of a move.
1565
+ // We check if we've previously seen a node change at the move destination.
1566
+ const entry = this.table.entries.getFirst(baseDetachId, countToProcess);
1567
+ result = { value: entry.value, length: entry.length };
1568
+ }
1569
+ // TODO: Consider moving this to a separate method so that this method can be side-effect free.
1570
+ if (result.value?.nodeChange !== undefined) {
1571
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(this.table.movedNodeToParent, result.value.nodeChange, {
1572
+ field: this.fieldId,
1573
+ });
1574
+ }
1575
+ return result;
1576
+ }
1577
+ composeAttachDetach(baseAttachId, newDetachId, count) {
1578
+ let countToProcess = count;
1579
+ const newAttachEntry = getFirstAttachField(this.table.newChange.crossFieldKeys, newDetachId, countToProcess);
1580
+ countToProcess = newAttachEntry.length;
1581
+ // Both changes can have the same ID if they came from inverse changesets.
1582
+ // If the new detach is part of a move,
1583
+ // then both input changesets contain the attach cross-field key for this ID.
1584
+ // The new attach may still exist in the composed changeset so we do not remove it here.
1585
+ // The new attach will typically cancel with a base detach,
1586
+ // in which case the cross-field key will be removed in `composeDetachAttach`.
1587
+ const hasNewAttachWithBaseAttachId = (0, index_js_2.areEqualChangeAtomIds)(baseAttachId, newDetachId) && newAttachEntry.value !== undefined;
1588
+ if (!hasNewAttachWithBaseAttachId) {
1589
+ this.table.removedCrossFieldKeys.set({ ...baseAttachId, target: crossFieldQueries_js_1.CrossFieldTarget.Destination }, countToProcess, true);
1590
+ }
1591
+ const baseDetachEntry = getFirstDetachField(this.table.baseChange.crossFieldKeys, baseAttachId, countToProcess);
1592
+ countToProcess = baseDetachEntry.length;
1593
+ const baseRootIdEntry = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseAttachId, countToProcess);
1594
+ countToProcess = baseRootIdEntry.length;
1595
+ const baseDetachId = baseRootIdEntry.value;
1596
+ if (baseDetachEntry.value === undefined) {
1597
+ const baseDetachLocationEntry = this.table.baseChange.rootNodes.detachLocations.getFirst(baseDetachId, countToProcess);
1598
+ countToProcess = baseDetachLocationEntry.length;
1599
+ // These nodes were detached in the base change's input context,
1600
+ // so the net effect of the two changes is a rename.
1601
+ appendNodeRename(this.table.composedRootNodes, baseAttachId, newDetachId, baseDetachEntry.length, this.table.baseChange.rootNodes, baseDetachLocationEntry.value ?? this.fieldId);
1602
+ this.table.removedCrossFieldKeys.set({ ...newDetachId, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, countToProcess, true);
1603
+ }
1604
+ else {
1605
+ // The base change moves these nodes.
1606
+ const prevEntry = this.table.entries.getFirst(baseAttachId, baseDetachEntry.length).value ?? {};
1607
+ this.table.entries.set(baseAttachId, baseDetachEntry.length, {
1608
+ ...prevEntry,
1609
+ detachId: newDetachId,
1610
+ });
1611
+ // The new detach will replace the base detach, so we remove the key for the base detach, unless they have the same ID.
1612
+ if (!(0, index_js_2.areEqualChangeAtomIds)(baseAttachId, newDetachId)) {
1613
+ this.table.removedCrossFieldKeys.set({ ...baseAttachId, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, countToProcess, true);
1614
+ }
1615
+ this.table.movedCrossFieldKeys.set({ ...newDetachId, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, countToProcess, baseDetachEntry.value);
1616
+ this.invalidateBaseFields([baseDetachEntry.value]);
1617
+ }
1618
+ if (newAttachEntry.value === undefined) {
1619
+ const newOutputDetachLocationEntry = this.table.newChange.rootNodes.outputDetachLocations.getFirst(newDetachId, countToProcess);
1620
+ countToProcess = newOutputDetachLocationEntry.length;
1621
+ this.table.composedRootNodes.outputDetachLocations.set(newDetachId, countToProcess, newOutputDetachLocationEntry.value ?? this.fieldId);
1622
+ }
1623
+ if (countToProcess < count) {
1624
+ const remainingCount = count - countToProcess;
1625
+ this.composeAttachDetach((0, index_js_2.offsetChangeAtomId)(baseAttachId, countToProcess), (0, index_js_2.offsetChangeAtomId)(newDetachId, countToProcess), remainingCount);
1626
+ }
1627
+ }
1628
+ sendNewChangesToBaseSourceLocation(baseAttachId, newChanges) {
1629
+ const { value: baseDetachId } = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseAttachId, 1);
1630
+ const detachFields = getFieldsForCrossFieldKey(this.table.baseChange, {
1631
+ ...baseDetachId,
1632
+ target: crossFieldQueries_js_1.CrossFieldTarget.Source,
1633
+ }, 1);
1634
+ if (detachFields.length > 0) {
1635
+ // The base attach is part of a move in the base changeset.
1636
+ const prevEntry = this.table.entries.getFirst(baseDetachId, 1).value ?? {};
1637
+ this.table.entries.set(baseDetachId, 1, { ...prevEntry, nodeChange: newChanges });
1638
+ if (newChanges !== undefined) {
1639
+ this.invalidateBaseFields(detachFields);
1640
+ }
1641
+ }
1642
+ else {
1643
+ const baseNodeId = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(this.table.baseChange.rootNodes.nodeChanges, baseDetachId);
1644
+ if (baseNodeId === undefined) {
1645
+ assignRootChange(this.table.composedRootNodes, this.table.movedNodeToParent, baseDetachId, newChanges, this.fieldId, this.table.rebaseVersion);
1331
1646
  }
1332
1647
  else {
1333
- const baseFieldIds = getFieldsForCrossFieldKey(this.table.baseChange, {
1334
- target,
1335
- revision,
1336
- localId: id,
1337
- }, count);
1338
- (0, internal_1.assert)(baseFieldIds.length > 0, 0x9c8 /* Cross field key not registered in base or new change */);
1339
- for (const baseFieldId of baseFieldIds) {
1340
- this.table.pendingCompositions.affectedBaseFields.set([baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field], true);
1341
- }
1648
+ addNodesToCompose(this.table, baseNodeId, newChanges);
1342
1649
  }
1343
1650
  }
1344
- super.set(target, revision, id, count, newValue, invalidateDependents);
1345
- }
1346
- onMoveIn(id) {
1347
- setInChangeAtomIdMap(this.table.composedNodeToParent, id, this.fieldId);
1348
1651
  }
1349
- moveKey(target, revision, id, count) {
1350
- throw new Error("Moving cross-field keys during compose is currently unsupported");
1652
+ areSameNodes(baseDetachId, newAttachId, count) {
1653
+ const renamedDetachEntry = firstAttachIdFromDetachId(this.table.composedRootNodes, baseDetachId, count);
1654
+ const isReattachOfSameNodes = (0, index_js_2.areEqualChangeAtomIds)(renamedDetachEntry.value, newAttachId);
1655
+ return { ...renamedDetachEntry, value: isReattachOfSameNodes };
1656
+ }
1657
+ composeDetachAttach(baseDetachId, newAttachId, count, composeToPin) {
1658
+ const areSameEntry = this.areSameNodes(baseDetachId, newAttachId, count);
1659
+ const countToProcess = areSameEntry.length;
1660
+ if (areSameEntry.value) {
1661
+ // These nodes have been moved back to their original location, so the composed changeset should not have any renames for them.
1662
+ // Note that deleting the rename from `this.table.composedRootNodes` would change the result of this method
1663
+ // if it were rerun due to the field being invalidated, so we instead record that the rename should be deleted later.
1664
+ this.table.renamesToDelete.set(baseDetachId, countToProcess, true);
1665
+ }
1666
+ if (composeToPin) {
1667
+ this.table.movedCrossFieldKeys.set({ target: crossFieldQueries_js_1.CrossFieldTarget.Source, ...newAttachId }, countToProcess, this.fieldId);
1668
+ if (!(0, index_js_2.areEqualChangeAtomIds)(baseDetachId, newAttachId)) {
1669
+ // The pin will have `newAttachId` as both its detach and attach ID.
1670
+ // So we remove `baseDetachId` unless that is equal to the pin's detach ID.
1671
+ this.table.removedCrossFieldKeys.set({ target: crossFieldQueries_js_1.CrossFieldTarget.Source, ...baseDetachId }, countToProcess, true);
1672
+ }
1673
+ // Note that while change2 should already have this key, change1 may have a rollback for the same ID in a different location.
1674
+ // In that case, change1's attach should be canceled out by a detach from change2.
1675
+ // Here we make sure that the composed change has the correct location (this field) for the attach ID.
1676
+ this.table.movedCrossFieldKeys.set({ target: crossFieldQueries_js_1.CrossFieldTarget.Destination, ...newAttachId }, countToProcess, this.fieldId);
1677
+ }
1678
+ else {
1679
+ this.table.removedCrossFieldKeys.set({ target: crossFieldQueries_js_1.CrossFieldTarget.Source, ...baseDetachId }, countToProcess, true);
1680
+ this.table.removedCrossFieldKeys.set({ target: crossFieldQueries_js_1.CrossFieldTarget.Destination, ...newAttachId }, countToProcess, true);
1681
+ }
1682
+ if (countToProcess < count) {
1683
+ this.composeAttachDetach((0, index_js_2.offsetChangeAtomId)(baseDetachId, countToProcess), (0, index_js_2.offsetChangeAtomId)(newAttachId, countToProcess), count - countToProcess);
1684
+ }
1351
1685
  }
1352
- get table() {
1353
- return this.crossFieldTable;
1686
+ invalidateBaseFields(fields) {
1687
+ if (this.allowInval) {
1688
+ for (const fieldId of fields) {
1689
+ this.table.pendingCompositions.affectedBaseFields.set(fieldIdKeyFromFieldId(fieldId), true);
1690
+ }
1691
+ }
1354
1692
  }
1355
1693
  }
1356
- function makeModularChangeset(props = {
1357
- maxId: -1,
1358
- }) {
1694
+ function makeModularChangeset(props) {
1695
+ const p = props ?? { maxId: -1 };
1359
1696
  const changeset = {
1360
- fieldChanges: props.fieldChanges ?? new Map(),
1361
- nodeChanges: props.nodeChanges ?? (0, index_js_2.newTupleBTree)(),
1362
- nodeToParent: props.nodeToParent ?? (0, index_js_2.newTupleBTree)(),
1363
- nodeAliases: props.nodeAliases ?? (0, index_js_2.newTupleBTree)(),
1364
- crossFieldKeys: props.crossFieldKeys ?? (0, modularChangeTypes_js_1.newCrossFieldKeyTable)(),
1697
+ rebaseVersion: p.rebaseVersion ?? 1,
1698
+ fieldChanges: p.fieldChanges ?? new Map(),
1699
+ nodeChanges: p.nodeChanges ?? (0, index_js_3.newTupleBTree)(),
1700
+ rootNodes: p.rootNodes ?? newRootTable(),
1701
+ nodeToParent: p.nodeToParent ?? (0, index_js_3.newTupleBTree)(),
1702
+ nodeAliases: p.nodeAliases ?? (0, index_js_3.newTupleBTree)(),
1703
+ crossFieldKeys: p.crossFieldKeys ?? (0, modularChangeTypes_js_1.newCrossFieldRangeTable)(),
1365
1704
  };
1366
- if (props.revisions !== undefined && props.revisions.length > 0) {
1367
- changeset.revisions = props.revisions;
1705
+ if (p.revisions !== undefined && p.revisions.length > 0) {
1706
+ changeset.revisions = p.revisions;
1707
+ }
1708
+ if (p.maxId >= 0) {
1709
+ changeset.maxId = (0, index_js_3.brand)(p.maxId);
1710
+ }
1711
+ if (p.constraintViolationCount !== undefined && p.constraintViolationCount > 0) {
1712
+ changeset.constraintViolationCount = p.constraintViolationCount;
1368
1713
  }
1369
- if (props.maxId >= 0) {
1370
- changeset.maxId = (0, index_js_2.brand)(props.maxId);
1714
+ if (p.constraintViolationCountOnRevert !== undefined &&
1715
+ p.constraintViolationCountOnRevert > 0) {
1716
+ changeset.constraintViolationCountOnRevert = p.constraintViolationCountOnRevert;
1371
1717
  }
1372
- if (props.constraintViolationCount !== undefined && props.constraintViolationCount > 0) {
1373
- changeset.constraintViolationCount = props.constraintViolationCount;
1718
+ if (p.noChangeConstraint !== undefined) {
1719
+ changeset.noChangeConstraint = p.noChangeConstraint;
1374
1720
  }
1375
- if (props.constraintViolationCountOnRevert !== undefined &&
1376
- props.constraintViolationCountOnRevert > 0) {
1377
- changeset.constraintViolationCountOnRevert = props.constraintViolationCountOnRevert;
1721
+ if (p.noChangeConstraintOnRevert !== undefined) {
1722
+ changeset.noChangeConstraintOnRevert = p.noChangeConstraintOnRevert;
1378
1723
  }
1379
- if (props.builds !== undefined && props.builds.size > 0) {
1380
- changeset.builds = props.builds;
1724
+ if (p.builds !== undefined && p.builds.size > 0) {
1725
+ changeset.builds = p.builds;
1381
1726
  }
1382
- if (props.destroys !== undefined && props.destroys.size > 0) {
1383
- changeset.destroys = props.destroys;
1727
+ if (p.destroys !== undefined && p.destroys.size > 0) {
1728
+ changeset.destroys = p.destroys;
1384
1729
  }
1385
- if (props.refreshers !== undefined && props.refreshers.size > 0) {
1386
- changeset.refreshers = props.refreshers;
1730
+ if (p.refreshers !== undefined && p.refreshers.size > 0) {
1731
+ changeset.refreshers = p.refreshers;
1387
1732
  }
1388
1733
  return changeset;
1389
1734
  }
1390
- class ModularEditBuilder extends index_js_1.EditBuilder {
1391
- constructor(family, fieldKinds, changeReceiver) {
1735
+ class ModularEditBuilder extends index_js_2.EditBuilder {
1736
+ constructor(family, fieldKinds, changeReceiver, codecOptions) {
1392
1737
  super(family, changeReceiver);
1393
1738
  this.fieldKinds = fieldKinds;
1394
1739
  this.transactionDepth = 0;
1395
- this.idAllocator = (0, index_js_2.idAllocatorFromMaxId)();
1740
+ this.idAllocator = (0, index_js_3.idAllocatorFromMaxId)();
1741
+ this.codecOptions = codecOptions;
1742
+ }
1743
+ isInTransaction() {
1744
+ return this.transactionDepth > 0;
1396
1745
  }
1397
1746
  enterTransaction() {
1398
1747
  this.transactionDepth += 1;
1399
1748
  if (this.transactionDepth === 1) {
1400
- this.idAllocator = (0, index_js_2.idAllocatorFromMaxId)();
1749
+ this.idAllocator = (0, index_js_3.idAllocatorFromMaxId)();
1401
1750
  }
1402
1751
  }
1403
1752
  exitTransaction() {
1404
1753
  (0, internal_1.assert)(this.transactionDepth > 0, 0x5b9 /* Cannot exit inexistent transaction */);
1405
1754
  this.transactionDepth -= 1;
1406
1755
  if (this.transactionDepth === 0) {
1407
- this.idAllocator = (0, index_js_2.idAllocatorFromMaxId)();
1756
+ this.idAllocator = (0, index_js_3.idAllocatorFromMaxId)();
1408
1757
  }
1409
1758
  }
1410
1759
  /**
@@ -1422,7 +1771,7 @@ class ModularEditBuilder extends index_js_1.EditBuilder {
1422
1771
  }
1423
1772
  // This content will be added to a GlobalEditDescription whose lifetime exceeds the scope of this function.
1424
1773
  content.referenceAdded();
1425
- const builds = (0, index_js_2.newTupleBTree)();
1774
+ const builds = (0, index_js_3.newTupleBTree)();
1426
1775
  builds.set([revision, firstId], content);
1427
1776
  return {
1428
1777
  type: "global",
@@ -1442,27 +1791,29 @@ class ModularEditBuilder extends index_js_1.EditBuilder {
1442
1791
  const modularChange = buildModularChangesetFromField({
1443
1792
  path: field,
1444
1793
  fieldChange: { fieldKind, change },
1445
- nodeChanges: (0, index_js_2.newTupleBTree)(),
1446
- nodeToParent: (0, index_js_2.newTupleBTree)(),
1447
- crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldKeyTable)(),
1794
+ nodeChanges: (0, index_js_3.newTupleBTree)(),
1795
+ nodeToParent: (0, index_js_3.newTupleBTree)(),
1796
+ crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldRangeTable)(),
1797
+ rootNodes: newRootTable(),
1448
1798
  idAllocator: this.idAllocator,
1449
1799
  localCrossFieldKeys,
1450
1800
  revision,
1451
1801
  });
1452
- this.applyChange((0, index_js_1.tagChange)(modularChange, revision));
1802
+ this.applyChange((0, index_js_2.tagChange)(modularChange, revision));
1453
1803
  }
1454
1804
  submitChanges(changes, revision) {
1455
1805
  const modularChange = this.buildChanges(changes);
1456
- this.applyChange((0, index_js_1.tagChange)(modularChange, revision));
1806
+ this.applyChange((0, index_js_2.tagChange)(modularChange, revision));
1457
1807
  }
1458
1808
  buildChanges(changes) {
1459
1809
  const revisions = new Set();
1460
1810
  const changeMaps = changes.map((change) => {
1461
1811
  revisions.add(change.revision);
1462
- return (0, index_js_1.makeAnonChange)(change.type === "global"
1812
+ return (0, index_js_2.makeAnonChange)(change.type === "global"
1463
1813
  ? makeModularChangeset({
1464
1814
  maxId: this.idAllocator.getMaxId(),
1465
1815
  builds: change.builds,
1816
+ rootNodes: renameTableFromRenameDescriptions(change.renames ?? []),
1466
1817
  revisions: [{ revision: change.revision }],
1467
1818
  })
1468
1819
  : buildModularChangesetFromField({
@@ -1471,38 +1822,40 @@ class ModularEditBuilder extends index_js_1.EditBuilder {
1471
1822
  fieldKind: change.fieldKind,
1472
1823
  change: change.change,
1473
1824
  },
1474
- nodeChanges: (0, index_js_2.newTupleBTree)(),
1475
- nodeToParent: (0, index_js_2.newTupleBTree)(),
1476
- crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldKeyTable)(),
1825
+ nodeChanges: (0, index_js_3.newTupleBTree)(),
1826
+ nodeToParent: (0, index_js_3.newTupleBTree)(),
1827
+ crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldRangeTable)(),
1828
+ rootNodes: newRootTable(),
1477
1829
  idAllocator: this.idAllocator,
1478
1830
  localCrossFieldKeys: getChangeHandler(this.fieldKinds, change.fieldKind).getCrossFieldKeys(change.change),
1479
1831
  revision: change.revision,
1480
1832
  }));
1481
1833
  });
1482
- const revInfo = Array.from(revisions).map((revision) => ({ revision }));
1834
+ const revInfo = [...revisions].map((revision) => ({ revision }));
1483
1835
  const composedChange = {
1484
1836
  ...this.changeFamily.rebaser.compose(changeMaps),
1485
1837
  revisions: revInfo,
1486
1838
  };
1487
- const maxId = (0, index_js_2.brand)(this.idAllocator.getMaxId());
1839
+ const maxId = (0, index_js_3.brand)(this.idAllocator.getMaxId());
1488
1840
  if (maxId >= 0) {
1489
1841
  composedChange.maxId = maxId;
1490
1842
  }
1491
1843
  return composedChange;
1492
1844
  }
1493
1845
  generateId(count) {
1494
- return (0, index_js_2.brand)(this.idAllocator.allocate(count));
1846
+ return (0, index_js_3.brand)(this.idAllocator.allocate(count));
1495
1847
  }
1496
1848
  addNodeExistsConstraint(path, revision) {
1497
1849
  const nodeChange = {
1498
1850
  nodeExistsConstraint: { violated: false },
1499
1851
  };
1500
- this.applyChange((0, index_js_1.tagChange)(buildModularChangesetFromNode({
1852
+ this.applyChange((0, index_js_2.tagChange)(buildModularChangesetFromNode({
1501
1853
  path,
1502
1854
  nodeChange,
1503
- nodeChanges: (0, index_js_2.newTupleBTree)(),
1504
- nodeToParent: (0, index_js_2.newTupleBTree)(),
1505
- crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldKeyTable)(),
1855
+ nodeChanges: (0, index_js_3.newTupleBTree)(),
1856
+ nodeToParent: (0, index_js_3.newTupleBTree)(),
1857
+ crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldRangeTable)(),
1858
+ rootNodes: newRootTable(),
1506
1859
  idAllocator: this.idAllocator,
1507
1860
  revision,
1508
1861
  }), revision));
@@ -1511,29 +1864,53 @@ class ModularEditBuilder extends index_js_1.EditBuilder {
1511
1864
  const nodeChange = {
1512
1865
  nodeExistsConstraintOnRevert: { violated: false },
1513
1866
  };
1514
- this.applyChange((0, index_js_1.tagChange)(buildModularChangesetFromNode({
1867
+ this.applyChange((0, index_js_2.tagChange)(buildModularChangesetFromNode({
1515
1868
  path,
1516
1869
  nodeChange,
1517
- nodeChanges: (0, index_js_2.newTupleBTree)(),
1518
- nodeToParent: (0, index_js_2.newTupleBTree)(),
1519
- crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldKeyTable)(),
1870
+ nodeChanges: (0, index_js_3.newTupleBTree)(),
1871
+ nodeToParent: (0, index_js_3.newTupleBTree)(),
1872
+ crossFieldKeys: (0, modularChangeTypes_js_1.newCrossFieldRangeTable)(),
1873
+ rootNodes: newRootTable(),
1520
1874
  idAllocator: this.idAllocator,
1521
1875
  revision,
1522
1876
  }), revision));
1523
1877
  }
1878
+ addNoChangeConstraint(revision) {
1879
+ if ((0, semver_ts_1.lt)(this.codecOptions.minVersionForCollab, index_js_1.FluidClientVersion.v2_80)) {
1880
+ throw new internal_2.UsageError(`No change constraints require min client version of at least ${index_js_1.FluidClientVersion.v2_80}`);
1881
+ }
1882
+ const changeset = makeModularChangeset({
1883
+ maxId: -1,
1884
+ noChangeConstraint: { violated: false },
1885
+ });
1886
+ this.applyChange((0, index_js_2.tagChange)(changeset, revision));
1887
+ }
1888
+ addNoChangeConstraintOnRevert(revision) {
1889
+ if ((0, semver_ts_1.lt)(this.codecOptions.minVersionForCollab, index_js_1.FluidClientVersion.v2_80)) {
1890
+ throw new internal_2.UsageError(`No change constraints require min client version of at least ${index_js_1.FluidClientVersion.v2_80}`);
1891
+ }
1892
+ const changeset = makeModularChangeset({
1893
+ maxId: -1,
1894
+ noChangeConstraintOnRevert: { violated: false },
1895
+ });
1896
+ this.applyChange((0, index_js_2.tagChange)(changeset, revision));
1897
+ }
1524
1898
  }
1525
1899
  exports.ModularEditBuilder = ModularEditBuilder;
1526
1900
  function buildModularChangesetFromField(props) {
1527
- const { path, fieldChange, nodeChanges, nodeToParent, crossFieldKeys, idAllocator = (0, index_js_2.idAllocatorFromMaxId)(), localCrossFieldKeys = [], childId, revision, } = props;
1901
+ const { path, fieldChange, nodeChanges, nodeToParent, crossFieldKeys, rootNodes, idAllocator = (0, index_js_3.idAllocatorFromMaxId)(), localCrossFieldKeys = [], childId, revision, } = props;
1528
1902
  const fieldChanges = new Map([[path.field, fieldChange]]);
1529
1903
  if (path.parent === undefined) {
1904
+ const field = { nodeId: undefined, field: path.field };
1530
1905
  for (const { key, count } of localCrossFieldKeys) {
1531
- crossFieldKeys.set(key, count, { nodeId: undefined, field: path.field });
1906
+ crossFieldKeys.set(key, count, field);
1532
1907
  }
1533
1908
  if (childId !== undefined) {
1534
- setInChangeAtomIdMap(nodeToParent, childId, {
1535
- nodeId: undefined,
1536
- field: path.field,
1909
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(nodeToParent, childId, {
1910
+ field: {
1911
+ nodeId: undefined,
1912
+ field: path.field,
1913
+ },
1537
1914
  });
1538
1915
  }
1539
1916
  return makeModularChangeset({
@@ -1541,6 +1918,7 @@ function buildModularChangesetFromField(props) {
1541
1918
  nodeChanges,
1542
1919
  nodeToParent,
1543
1920
  crossFieldKeys,
1921
+ rootNodes,
1544
1922
  maxId: idAllocator.getMaxId(),
1545
1923
  revisions: [{ revision }],
1546
1924
  });
@@ -1548,14 +1926,14 @@ function buildModularChangesetFromField(props) {
1548
1926
  const nodeChangeset = {
1549
1927
  fieldChanges,
1550
1928
  };
1551
- const parentId = { localId: (0, index_js_2.brand)(idAllocator.allocate()), revision };
1929
+ const parentId = { localId: (0, index_js_3.brand)(idAllocator.allocate()), revision };
1930
+ const fieldId = { nodeId: parentId, field: path.field };
1552
1931
  for (const { key, count } of localCrossFieldKeys) {
1553
1932
  crossFieldKeys.set(key, count, { nodeId: parentId, field: path.field });
1554
1933
  }
1555
1934
  if (childId !== undefined) {
1556
- setInChangeAtomIdMap(nodeToParent, childId, {
1557
- nodeId: parentId,
1558
- field: path.field,
1935
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(nodeToParent, childId, {
1936
+ field: fieldId,
1559
1937
  });
1560
1938
  }
1561
1939
  return buildModularChangesetFromNode({
@@ -1564,52 +1942,67 @@ function buildModularChangesetFromField(props) {
1564
1942
  nodeChanges,
1565
1943
  nodeToParent,
1566
1944
  crossFieldKeys,
1945
+ rootNodes,
1567
1946
  idAllocator,
1568
1947
  revision,
1569
1948
  nodeId: parentId,
1570
1949
  });
1571
1950
  }
1951
+ exports.buildModularChangesetFromField = buildModularChangesetFromField;
1572
1952
  function buildModularChangesetFromNode(props) {
1573
- const { path, nodeId = { localId: (0, index_js_2.brand)(props.idAllocator.allocate()), revision: props.revision }, } = props;
1574
- setInChangeAtomIdMap(props.nodeChanges, nodeId, props.nodeChange);
1575
- const fieldChangeset = genericFieldKind_js_1.genericFieldKind.changeHandler.editor.buildChildChanges([
1576
- [path.parentIndex, nodeId],
1577
- ]);
1578
- const fieldChange = {
1579
- fieldKind: genericFieldKind_js_1.genericFieldKind.identifier,
1580
- change: fieldChangeset,
1581
- };
1582
- return buildModularChangesetFromField({
1583
- ...props,
1584
- path: { parent: path.parent, field: path.parentField },
1585
- fieldChange,
1586
- localCrossFieldKeys: [],
1587
- childId: nodeId,
1588
- });
1953
+ const { path, idAllocator, revision, nodeChanges, nodeChange, nodeId = { localId: (0, index_js_3.brand)(idAllocator.allocate()), revision }, } = props;
1954
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(nodeChanges, nodeId, nodeChange);
1955
+ if ((0, index_js_2.isDetachedUpPathRoot)(path)) {
1956
+ props.rootNodes.nodeChanges.set([path.detachedNodeId.major, (0, index_js_3.brand)(path.detachedNodeId.minor)], nodeId);
1957
+ return makeModularChangeset({
1958
+ rootNodes: props.rootNodes,
1959
+ nodeChanges: props.nodeChanges,
1960
+ nodeToParent: props.nodeToParent,
1961
+ crossFieldKeys: props.crossFieldKeys,
1962
+ maxId: props.idAllocator.getMaxId(),
1963
+ revisions: [{ revision: props.revision }],
1964
+ });
1965
+ }
1966
+ else {
1967
+ const fieldChangeset = genericFieldKind_js_1.genericFieldKind.changeHandler.editor.buildChildChanges([
1968
+ [path.parentIndex, nodeId],
1969
+ ]);
1970
+ const fieldChange = {
1971
+ fieldKind: genericFieldKind_js_1.genericFieldKind.identifier,
1972
+ change: fieldChangeset,
1973
+ };
1974
+ return buildModularChangesetFromField({
1975
+ ...props,
1976
+ path: { parent: path.parent, field: path.parentField },
1977
+ fieldChange,
1978
+ localCrossFieldKeys: [],
1979
+ childId: nodeId,
1980
+ });
1981
+ }
1982
+ }
1983
+ function renameTableFromRenameDescriptions(renames) {
1984
+ const table = newRootTable();
1985
+ for (const rename of renames) {
1986
+ addNodeRename(table, rename.oldId, rename.newId, rename.count, rename.detachLocation);
1987
+ }
1988
+ return table;
1589
1989
  }
1590
1990
  function getRevInfoFromTaggedChanges(changes) {
1591
1991
  let maxId = -1;
1592
1992
  const revInfos = [];
1993
+ const revisions = new Set();
1593
1994
  for (const taggedChange of changes) {
1594
1995
  const change = taggedChange.change;
1595
1996
  maxId = Math.max(change.maxId ?? -1, maxId);
1596
- revInfos.push(...revisionInfoFromTaggedChange(taggedChange));
1597
- }
1598
- const revisions = new Set();
1599
- const rolledBackRevisions = [];
1600
- for (const info of revInfos) {
1601
- revisions.add(info.revision);
1602
- if (info.rollbackOf !== undefined) {
1603
- rolledBackRevisions.push(info.rollbackOf);
1604
- }
1605
- }
1606
- rolledBackRevisions.reverse();
1607
- for (const revision of rolledBackRevisions) {
1608
- if (!revisions.has(revision)) {
1609
- revInfos.push({ revision });
1997
+ const infosToAdd = revisionInfoFromTaggedChange(taggedChange);
1998
+ for (const info of infosToAdd) {
1999
+ if (!revisions.has(info.revision)) {
2000
+ revisions.add(info.revision);
2001
+ revInfos.push(info);
2002
+ }
1610
2003
  }
1611
2004
  }
1612
- return { maxId: (0, index_js_2.brand)(maxId), revInfos };
2005
+ return { maxId: (0, index_js_3.brand)(maxId), revInfos };
1613
2006
  }
1614
2007
  function revisionInfoFromTaggedChange(taggedChange) {
1615
2008
  const revInfos = [];
@@ -1625,15 +2018,16 @@ function revisionInfoFromTaggedChange(taggedChange) {
1625
2018
  }
1626
2019
  return revInfos;
1627
2020
  }
1628
- function fieldChangeFromId(fields, nodes, id) {
1629
- const fieldMap = fieldMapFromNodeId(fields, nodes, id.nodeId);
2021
+ function fieldChangeFromId(change, id) {
2022
+ const fieldId = normalizeFieldId(id, change.nodeAliases);
2023
+ const fieldMap = fieldMapFromNodeId(change.fieldChanges, change.nodeChanges, change.nodeAliases, fieldId.nodeId);
1630
2024
  return fieldMap.get(id.field) ?? (0, internal_1.fail)(0xb25 /* No field exists for the given ID */);
1631
2025
  }
1632
- function fieldMapFromNodeId(rootFieldMap, nodes, nodeId) {
2026
+ function fieldMapFromNodeId(rootFieldMap, nodes, aliases, nodeId) {
1633
2027
  if (nodeId === undefined) {
1634
2028
  return rootFieldMap;
1635
2029
  }
1636
- const node = nodeChangeFromId(nodes, nodeId);
2030
+ const node = nodeChangeFromId(nodes, aliases, nodeId);
1637
2031
  (0, internal_1.assert)(node.fieldChanges !== undefined, 0x9c9 /* Expected node to have field changes */);
1638
2032
  return node.fieldChanges;
1639
2033
  }
@@ -1644,48 +2038,74 @@ function rebasedFieldIdFromBaseId(table, baseId) {
1644
2038
  return { ...baseId, nodeId: rebasedNodeIdFromBaseNodeId(table, baseId.nodeId) };
1645
2039
  }
1646
2040
  function rebasedNodeIdFromBaseNodeId(table, baseId) {
1647
- return getFromChangeAtomIdMap(table.baseToRebasedNodeId, baseId) ?? baseId;
2041
+ return (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(table.baseToRebasedNodeId, baseId) ?? baseId;
1648
2042
  }
1649
- function nodeChangeFromId(nodes, id) {
1650
- const node = getFromChangeAtomIdMap(nodes, id);
2043
+ function nodeChangeFromId(nodes, aliases, id) {
2044
+ const normalizedId = normalizeNodeId(id, aliases);
2045
+ const node = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(nodes, normalizedId);
1651
2046
  (0, internal_1.assert)(node !== undefined, 0x9ca /* Unknown node ID */);
1652
2047
  return node;
1653
2048
  }
1654
2049
  function fieldIdFromFieldIdKey([revision, localId, field]) {
1655
- const nodeId = localId !== undefined ? { revision, localId } : undefined;
2050
+ const nodeId = localId === undefined ? undefined : { revision, localId };
1656
2051
  return { nodeId, field };
1657
2052
  }
2053
+ function fieldIdKeyFromFieldId(fieldId) {
2054
+ return [fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field];
2055
+ }
1658
2056
  function cloneNodeChangeset(nodeChangeset) {
1659
2057
  if (nodeChangeset.fieldChanges !== undefined) {
1660
2058
  return { ...nodeChangeset, fieldChanges: new Map(nodeChangeset.fieldChanges) };
1661
2059
  }
1662
2060
  return { ...nodeChangeset };
1663
2061
  }
1664
- function replaceFieldIdRevision(fieldId, oldRevisions, newRevision) {
2062
+ function replaceNodeLocationRevision(location, replacer) {
2063
+ return location.field === undefined
2064
+ ? { root: replacer.getUpdatedAtomId(location.root) }
2065
+ : { field: replaceFieldIdRevision(location.field, replacer) };
2066
+ }
2067
+ function replaceFieldIdRevision(fieldId, replacer) {
1665
2068
  if (fieldId.nodeId === undefined) {
1666
2069
  return fieldId;
1667
2070
  }
1668
2071
  return {
1669
2072
  ...fieldId,
1670
- nodeId: (0, index_js_1.replaceAtomRevisions)(fieldId.nodeId, oldRevisions, newRevision),
2073
+ nodeId: replacer.getUpdatedAtomId(fieldId.nodeId),
1671
2074
  };
1672
2075
  }
1673
- function getParentFieldId(changeset, nodeId) {
1674
- const parentId = getFromChangeAtomIdMap(changeset.nodeToParent, nodeId);
1675
- (0, internal_1.assert)(parentId !== undefined, 0x9cb /* Parent field should be defined */);
1676
- return normalizeFieldId(parentId, changeset.nodeAliases);
2076
+ function getNodeParent(changeset, nodeId) {
2077
+ const normalizedNodeId = normalizeNodeId(nodeId, changeset.nodeAliases);
2078
+ const location = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(changeset.nodeToParent, normalizedNodeId);
2079
+ (0, internal_1.assert)(location !== undefined, 0x9cb /* Parent field should be defined */);
2080
+ if (location.field !== undefined) {
2081
+ return { field: normalizeFieldId(location.field, changeset.nodeAliases) };
2082
+ }
2083
+ return location;
1677
2084
  }
1678
- exports.getParentFieldId = getParentFieldId;
2085
+ exports.getNodeParent = getNodeParent;
1679
2086
  function getFieldsForCrossFieldKey(changeset, key, count) {
1680
2087
  return changeset.crossFieldKeys
1681
2088
  .getAll(key, count)
1682
2089
  .map(({ value: fieldId }) => normalizeFieldId(fieldId, changeset.nodeAliases));
1683
2090
  }
2091
+ function getFirstFieldForCrossFieldKey(changeset, key, count) {
2092
+ const result = changeset.crossFieldKeys.getFirst(key, count);
2093
+ if (result.value === undefined) {
2094
+ return result;
2095
+ }
2096
+ return { ...result, value: normalizeFieldId(result.value, changeset.nodeAliases) };
2097
+ }
2098
+ function normalizeNodeLocation(location, nodeAliases) {
2099
+ if (location.field !== undefined) {
2100
+ return { field: normalizeFieldId(location.field, nodeAliases) };
2101
+ }
2102
+ return location;
2103
+ }
1684
2104
  // This is only exported for use in test utilities.
1685
2105
  function normalizeFieldId(fieldId, nodeAliases) {
1686
- return fieldId.nodeId !== undefined
1687
- ? { ...fieldId, nodeId: normalizeNodeId(fieldId.nodeId, nodeAliases) }
1688
- : fieldId;
2106
+ return fieldId.nodeId === undefined
2107
+ ? fieldId
2108
+ : { ...fieldId, nodeId: normalizeNodeId(fieldId.nodeId, nodeAliases) };
1689
2109
  }
1690
2110
  exports.normalizeFieldId = normalizeFieldId;
1691
2111
  /**
@@ -1693,25 +2113,509 @@ exports.normalizeFieldId = normalizeFieldId;
1693
2113
  */
1694
2114
  function normalizeNodeId(nodeId, nodeAliases) {
1695
2115
  let currentId = nodeId;
2116
+ let cycleProbeId = nodeId;
1696
2117
  // eslint-disable-next-line no-constant-condition
1697
2118
  while (true) {
1698
- const dealiased = getFromChangeAtomIdMap(nodeAliases, currentId);
2119
+ const dealiased = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(nodeAliases, currentId);
1699
2120
  if (dealiased === undefined) {
1700
2121
  return currentId;
1701
2122
  }
1702
2123
  currentId = dealiased;
2124
+ if (cycleProbeId !== undefined) {
2125
+ cycleProbeId = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(nodeAliases, cycleProbeId);
2126
+ }
2127
+ if (cycleProbeId !== undefined) {
2128
+ cycleProbeId = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(nodeAliases, cycleProbeId);
2129
+ }
2130
+ (0, internal_1.assert)(!(0, index_js_2.areEqualChangeAtomIdOpts)(cycleProbeId, currentId), "Alias cycle detected");
1703
2131
  }
1704
2132
  }
2133
+ exports.normalizeNodeId = normalizeNodeId;
1705
2134
  function hasConflicts(change) {
1706
2135
  return (change.constraintViolationCount ?? 0) > 0;
1707
2136
  }
1708
- function getFromChangeAtomIdMap(map, id) {
1709
- return map.get([id.revision, id.localId]);
2137
+ function areEqualFieldIds(a, b) {
2138
+ return (0, index_js_2.areEqualChangeAtomIdOpts)(a.nodeId, b.nodeId) && a.field === b.field;
2139
+ }
2140
+ function firstAttachIdFromDetachId(roots, detachId, count) {
2141
+ const result = roots.oldToNewId.getFirst(detachId, count);
2142
+ return { ...result, value: result.value ?? detachId };
1710
2143
  }
1711
- function setInChangeAtomIdMap(map, id, value) {
1712
- map.set([id.revision, id.localId], value);
2144
+ function firstDetachIdFromAttachId(roots, attachId, count) {
2145
+ const result = roots.newToOldId.getFirst(attachId, count);
2146
+ return { ...result, start: attachId, value: result.value ?? attachId };
1713
2147
  }
1714
- function areEqualFieldIds(a, b) {
1715
- return (0, index_js_1.areEqualChangeAtomIdOpts)(a.nodeId, b.nodeId) && a.field === b.field;
2148
+ function rebaseCrossFieldKeys(sourceTable, movedDetaches, newDetachLocations) {
2149
+ const rebasedTable = sourceTable.clone();
2150
+ for (const entry of movedDetaches.entries()) {
2151
+ rebasedTable.delete({ ...entry.start, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, entry.length);
2152
+ }
2153
+ for (const entry of newDetachLocations.entries()) {
2154
+ rebasedTable.set({ ...entry.start, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, entry.length, entry.value);
2155
+ }
2156
+ return rebasedTable;
2157
+ }
2158
+ function newRootTable() {
2159
+ return {
2160
+ newToOldId: (0, index_js_2.newChangeAtomIdTransform)(),
2161
+ oldToNewId: (0, index_js_2.newChangeAtomIdTransform)(),
2162
+ nodeChanges: (0, index_js_3.newTupleBTree)(),
2163
+ detachLocations: (0, index_js_2.newChangeAtomIdRangeMap)(),
2164
+ outputDetachLocations: (0, index_js_2.newChangeAtomIdRangeMap)(),
2165
+ };
2166
+ }
2167
+ exports.newRootTable = newRootTable;
2168
+ function rebaseRoots(change, base, affectedBaseFields, nodesToRebase, rebasedNodeToParent, rebaseVersion) {
2169
+ const rebasedRoots = newRootTable();
2170
+ for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
2171
+ rebaseRename(change.rootNodes, rebasedRoots, renameEntry, base, affectedBaseFields);
2172
+ }
2173
+ for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
2174
+ const changes = base.rootNodes.nodeChanges.get(detachIdKey);
2175
+ if (changes !== undefined) {
2176
+ nodesToRebase.push([nodeId, changes]);
2177
+ }
2178
+ const detachId = (0, index_js_2.makeChangeAtomId)(detachIdKey[1], detachIdKey[0]);
2179
+ const attachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
2180
+ const baseAttachEntry = base.crossFieldKeys.getFirst({ target: crossFieldQueries_js_1.CrossFieldTarget.Destination, ...attachId }, 1);
2181
+ if (baseAttachEntry.value === undefined) {
2182
+ const renamedDetachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
2183
+ const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(renamedDetachId, 1).value;
2184
+ if (baseOutputDetachLocation !== undefined) {
2185
+ affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
2186
+ }
2187
+ const detachLocation = baseOutputDetachLocation ??
2188
+ change.rootNodes.detachLocations.getFirst(detachId, 1).value;
2189
+ // Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
2190
+ // We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
2191
+ assignRootChange(rebasedRoots, rebasedNodeToParent, renamedDetachId, nodeId, detachLocation, rebaseVersion);
2192
+ }
2193
+ else {
2194
+ affectedBaseFields.set(fieldIdKeyFromFieldId(baseAttachEntry.value), true);
2195
+ rebasedNodeToParent.delete(detachIdKey);
2196
+ }
2197
+ }
2198
+ for (const entry of change.rootNodes.outputDetachLocations.entries()) {
2199
+ rebasedRoots.outputDetachLocations.set(entry.start, entry.length, entry.value);
2200
+ }
2201
+ return rebasedRoots;
2202
+ }
2203
+ function rebaseRename(newRoots, rebasedRoots, renameEntry, base, affectedBaseFields) {
2204
+ let count = renameEntry.length;
2205
+ const baseRenameEntry = firstAttachIdFromDetachId(base.rootNodes, renameEntry.start, count);
2206
+ count = baseRenameEntry.length;
2207
+ const baseAttachEntry = base.crossFieldKeys.getFirst({
2208
+ ...baseRenameEntry.value,
2209
+ target: crossFieldQueries_js_1.CrossFieldTarget.Destination,
2210
+ }, count);
2211
+ count = baseAttachEntry.length;
2212
+ if (baseAttachEntry.value === undefined) {
2213
+ const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(baseRenameEntry.value, 1).value;
2214
+ if (baseOutputDetachLocation !== undefined) {
2215
+ affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
2216
+ }
2217
+ const detachEntry = newRoots.detachLocations.getFirst(renameEntry.start, count);
2218
+ count = detachEntry.length;
2219
+ const detachLocation = baseOutputDetachLocation ?? detachEntry.value;
2220
+ // Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
2221
+ // We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
2222
+ addNodeRename(rebasedRoots, baseRenameEntry.value, renameEntry.value, count, detachLocation);
2223
+ }
2224
+ else {
2225
+ // This rename represents an intention to detach these nodes.
2226
+ // The rebased change should have a detach in the field where the base change attaches the nodes,
2227
+ // so we need to ensure that field is processed.
2228
+ affectedBaseFields.set(fieldIdKeyFromFieldId(normalizeFieldId(baseAttachEntry.value, base.nodeAliases)), true);
2229
+ }
2230
+ const countRemaining = renameEntry.length - count;
2231
+ if (countRemaining > 0) {
2232
+ rebaseRename(newRoots, rebasedRoots, {
2233
+ start: (0, index_js_2.offsetChangeAtomId)(renameEntry.start, count),
2234
+ value: (0, index_js_2.offsetChangeAtomId)(renameEntry.value, count),
2235
+ length: countRemaining,
2236
+ }, base, affectedBaseFields);
2237
+ }
2238
+ }
2239
+ /**
2240
+ * For each root detach location, replaces any node ID from the base changeset
2241
+ * with the corresponding ID in the new changeset.
2242
+ */
2243
+ function fixupRebasedDetachLocations(table) {
2244
+ for (const { start, length, value: detachLocation, } of table.rebasedRootNodes.detachLocations.entries()) {
2245
+ const normalizedDetachLocation = normalizeFieldId(detachLocation, table.baseChange.nodeAliases);
2246
+ if (normalizedDetachLocation.nodeId !== undefined) {
2247
+ const rebasedNodeId = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(table.baseToRebasedNodeId, normalizedDetachLocation.nodeId);
2248
+ if (rebasedNodeId !== undefined) {
2249
+ table.rebasedRootNodes.detachLocations.set(start, length, {
2250
+ ...normalizedDetachLocation,
2251
+ nodeId: rebasedNodeId,
2252
+ });
2253
+ }
2254
+ }
2255
+ }
2256
+ }
2257
+ function addNodesToCompose(table, id1, id2) {
2258
+ const normalizedId1 = normalizeNodeId(id1, table.baseChange.nodeAliases);
2259
+ const normalizedId2 = normalizeNodeId(id2, table.newChange.nodeAliases);
2260
+ if ((0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(table.newToBaseNodeId, normalizedId2) === undefined) {
2261
+ (0, changeAtomIdBTree_js_1.setInChangeAtomIdMap)(table.newToBaseNodeId, normalizedId2, normalizedId1);
2262
+ table.pendingCompositions.nodeIdsToCompose.push([normalizedId1, normalizedId2]);
2263
+ }
2264
+ }
2265
+ function composeRevInfos(revisions1, revisions2) {
2266
+ if (revisions1?.length === 1 &&
2267
+ revisions2?.length === 1 &&
2268
+ revisions1[0]?.revision === revisions2[0]?.revision) {
2269
+ // This is a special case where we are composing two changesets from the same transaction.
2270
+ // We return one of the input arrays to avoid duplicating revision entries.
2271
+ return revisions1;
2272
+ }
2273
+ const result = [...(revisions1 ?? []), ...(revisions2 ?? [])];
2274
+ return result;
2275
+ }
2276
+ function composeCrossFieldKeyTables(table1, table2, movedCrossFieldKeys, removedCrossFieldKeys) {
2277
+ const composedTable = index_js_3.RangeMap.union(table1, table2);
2278
+ for (const entry of movedCrossFieldKeys.entries()) {
2279
+ composedTable.set(entry.start, entry.length, entry.value);
2280
+ }
2281
+ for (const entry of removedCrossFieldKeys.entries()) {
2282
+ composedTable.delete(entry.start, entry.length);
2283
+ }
2284
+ return composedTable;
2285
+ }
2286
+ function composeRootTables(change1, change2, composedNodeToParent, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions) {
2287
+ const composedTable = cloneRootTable(change1.rootNodes);
2288
+ for (const renameEntry of change2.rootNodes.oldToNewId.entries()) {
2289
+ composeRename(change1, change2, composedTable, renameEntry.start, renameEntry.value, renameEntry.length, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
2290
+ }
2291
+ for (const [[revision2, id2], nodeId2] of change2.rootNodes.nodeChanges.entries()) {
2292
+ const detachId2 = { revision: revision2, localId: id2 };
2293
+ const detachId1 = firstDetachIdFromAttachId(change1.rootNodes, detachId2, 1).value;
2294
+ const nodeId1 = (0, changeAtomIdBTree_js_1.getFromChangeAtomIdMap)(change1.rootNodes.nodeChanges, detachId1);
2295
+ if (nodeId1 === undefined) {
2296
+ const fieldId = getFieldsForCrossFieldKey(change1, { ...detachId1, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, 1)[0];
2297
+ if (fieldId === undefined) {
2298
+ assignRootChange(composedTable, composedNodeToParent, detachId1, nodeId2, change1.rootNodes.detachLocations.getFirst(detachId1, 1).value ??
2299
+ change2.rootNodes.detachLocations.getFirst(detachId2, 1).value, Math.max(change1.rebaseVersion, change2.rebaseVersion));
2300
+ }
2301
+ else {
2302
+ // In this case, this node is attached in the input context of change1,
2303
+ // and is represented in detachFieldId.
2304
+ pendingCompositions.affectedBaseFields.set([fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field], true);
2305
+ }
2306
+ }
2307
+ else {
2308
+ pendingCompositions.nodeIdsToCompose.push([nodeId1, nodeId2]);
2309
+ }
2310
+ }
2311
+ for (const outputDetachEntry of change1.rootNodes.outputDetachLocations.entries()) {
2312
+ composeOutputDetachLocation(outputDetachEntry.start, outputDetachEntry.length, outputDetachEntry.value, change2, composedTable);
2313
+ }
2314
+ for (const entry of change2.rootNodes.outputDetachLocations.entries()) {
2315
+ composedTable.outputDetachLocations.set(entry.start, entry.length, entry.value);
2316
+ }
2317
+ return composedTable;
2318
+ }
2319
+ function composeOutputDetachLocation(outputDetachId1, count, detachLocation, change2, composedTable) {
2320
+ let countToProcess = count;
2321
+ const renameEntry = firstAttachIdFromDetachId(change2.rootNodes, outputDetachId1, countToProcess);
2322
+ countToProcess = renameEntry.length;
2323
+ const attachEntry = getFirstAttachField(change2.crossFieldKeys, renameEntry.value, countToProcess);
2324
+ countToProcess = attachEntry.length;
2325
+ composedTable.outputDetachLocations.delete(outputDetachId1, countToProcess);
2326
+ if (attachEntry.value === undefined) {
2327
+ // We update the key for the detach location to the renamed ID of the root in the composed output context.
2328
+ composedTable.outputDetachLocations.set(renameEntry.value, countToProcess, detachLocation);
2329
+ }
2330
+ else {
2331
+ // These nodes are attached by `change2` and thus attached in the composed output context,
2332
+ // so there should be no output detach location.
2333
+ }
2334
+ const countRemaining = count - countToProcess;
2335
+ if (countRemaining > 0) {
2336
+ composeOutputDetachLocation((0, index_js_2.offsetChangeAtomId)(outputDetachId1, countToProcess), countRemaining, detachLocation, change2, composedTable);
2337
+ }
2338
+ }
2339
+ function composeRename(change1, change2, mergedTable, oldId, newId, count, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions) {
2340
+ let countToProcess = count;
2341
+ const detachEntry = getFirstDetachField(change1.crossFieldKeys, oldId, countToProcess);
2342
+ countToProcess = detachEntry.length;
2343
+ if (detachEntry.value === undefined) {
2344
+ // `change1` may also have a rename to `renameEntry.value`, in which case it must refer to a different node.
2345
+ // That node must have been attached by `change1` and detached by `change2`.
2346
+ // The final rename for that node will be created in `composeAttachDetach`.
2347
+ // We delete any such rename for now to avoid colliding with the rename currently being processed.
2348
+ deleteNodeRenameTo(mergedTable, newId, countToProcess);
2349
+ // The nodes were detached before `change`, so we append this rename.
2350
+ appendNodeRename(mergedTable, oldId, newId, countToProcess, change1.rootNodes, change2.rootNodes.detachLocations.getFirst(oldId, countToProcess).value);
2351
+ }
2352
+ else {
2353
+ // `change1` detached these nodes,
2354
+ // so we invalidate the detach location so that the detach's ID can be replaced with the new ID.
2355
+ pendingCompositions.affectedBaseFields.set(fieldIdKeyFromFieldId(detachEntry.value), true);
2356
+ if (!(0, index_js_2.areEqualChangeAtomIds)(oldId, newId)) {
2357
+ // `change1`'s detach will be replaced by `change2`'s detach, so we update the cross-field keys.
2358
+ removedCrossFieldKeys.set({ ...oldId, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, countToProcess, true);
2359
+ }
2360
+ movedCrossFieldKeys.set({ ...newId, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, countToProcess, detachEntry.value);
2361
+ }
2362
+ if (countToProcess < count) {
2363
+ composeRename(change1, change2, mergedTable, (0, index_js_2.offsetChangeAtomId)(oldId, countToProcess), (0, index_js_2.offsetChangeAtomId)(newId, countToProcess), count - countToProcess, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
2364
+ }
2365
+ }
2366
+ function cloneRootTable(table) {
2367
+ return {
2368
+ oldToNewId: table.oldToNewId.clone(),
2369
+ newToOldId: table.newToOldId.clone(),
2370
+ nodeChanges: (0, index_js_3.brand)(table.nodeChanges.clone()),
2371
+ detachLocations: table.detachLocations.clone(),
2372
+ outputDetachLocations: table.outputDetachLocations.clone(),
2373
+ };
2374
+ }
2375
+ exports.cloneRootTable = cloneRootTable;
2376
+ function invertRootTable(change, isRollback) {
2377
+ const invertedRoots = newRootTable();
2378
+ for (const [[revision, localId], nodeId] of change.rootNodes.nodeChanges.entries()) {
2379
+ const detachId = { revision, localId };
2380
+ const renamedId = firstAttachIdFromDetachId(change.rootNodes, detachId, 1).value;
2381
+ // This checks whether `change` attaches this node.
2382
+ // If it does, the node is not detached in the input context of the inverse, and so should not be included in the root table.
2383
+ if (change.crossFieldKeys.getFirst({ ...renamedId, target: crossFieldQueries_js_1.CrossFieldTarget.Destination }, 1)
2384
+ .value === undefined) {
2385
+ assignRootChange(invertedRoots, undefined, renamedId, nodeId, change.rootNodes.detachLocations.getFirst(detachId, 1).value, change.rebaseVersion);
2386
+ }
2387
+ }
2388
+ if (isRollback) {
2389
+ // We only invert renames of nodes which are not attached or detached by this changeset.
2390
+ // When we invert an attach we will create a detach which incorporates the rename.
2391
+ for (const { start: oldId, value: newId, length, } of change.rootNodes.oldToNewId.entries()) {
2392
+ invertRename(change, invertedRoots, oldId, newId, length);
2393
+ }
2394
+ }
2395
+ return invertedRoots;
2396
+ }
2397
+ function invertRename(change, invertedRoots, oldId, newId, length) {
2398
+ for (const detachEntry of doesChangeDetachNodes(change.crossFieldKeys, newId, length)) {
2399
+ (0, internal_1.assert)(!detachEntry.value, "A changeset should not have a rename and detach for the same node.");
2400
+ }
2401
+ let countProcessed = length;
2402
+ const attachEntry = getFirstAttachField(change.crossFieldKeys, newId, countProcessed);
2403
+ countProcessed = attachEntry.length;
2404
+ if (attachEntry.value === undefined) {
2405
+ const outputDetachEntry = change.rootNodes.outputDetachLocations.getFirst(newId, countProcessed);
2406
+ countProcessed = outputDetachEntry.length;
2407
+ const inputDetachEntry = change.rootNodes.detachLocations.getFirst(oldId, countProcessed);
2408
+ countProcessed = inputDetachEntry.length;
2409
+ addNodeRename(invertedRoots, newId, oldId, countProcessed, outputDetachEntry.value ?? inputDetachEntry.value);
2410
+ }
2411
+ if (countProcessed < length) {
2412
+ invertRename(change, invertedRoots, (0, index_js_2.offsetChangeAtomId)(oldId, countProcessed), (0, index_js_2.offsetChangeAtomId)(newId, countProcessed), length - countProcessed);
2413
+ }
2414
+ }
2415
+ function doesChangeAttachNodes(table, id, count) {
2416
+ return table
2417
+ .getAll2({ ...id, target: crossFieldQueries_js_1.CrossFieldTarget.Destination }, count)
2418
+ .map((entry) => ({ ...entry, value: entry.value !== undefined }));
2419
+ }
2420
+ function doesChangeDetachNodes(table, id, count) {
2421
+ return table
2422
+ .getAll2({ ...id, target: crossFieldQueries_js_1.CrossFieldTarget.Source }, count)
2423
+ .map((entry) => ({ ...entry, value: entry.value !== undefined }));
2424
+ }
2425
+ function getFirstDetachField(table, id, count) {
2426
+ return table.getFirst({ target: crossFieldQueries_js_1.CrossFieldTarget.Source, ...id }, count);
2427
+ }
2428
+ exports.getFirstDetachField = getFirstDetachField;
2429
+ function getFirstAttachField(table, id, count) {
2430
+ return table.getFirst({ target: crossFieldQueries_js_1.CrossFieldTarget.Destination, ...id }, count);
2431
+ }
2432
+ exports.getFirstAttachField = getFirstAttachField;
2433
+ function addNodeRename(table, oldId, newId, count, detachLocation) {
2434
+ if ((0, index_js_2.areEqualChangeAtomIds)(oldId, newId)) {
2435
+ return;
2436
+ }
2437
+ for (const entry of table.oldToNewId.getAll2(oldId, count)) {
2438
+ (0, internal_1.assert)(entry.value === undefined ||
2439
+ (0, index_js_2.areEqualChangeAtomIds)(entry.value, (0, index_js_2.offsetChangeAtomId)(newId, entry.offset)), "Rename collision detected");
2440
+ }
2441
+ for (const entry of table.newToOldId.getAll2(newId, count)) {
2442
+ (0, internal_1.assert)(entry.value === undefined ||
2443
+ (0, index_js_2.areEqualChangeAtomIds)(entry.value, (0, index_js_2.offsetChangeAtomId)(oldId, entry.offset)), "Rename collision detected");
2444
+ }
2445
+ table.oldToNewId.set(oldId, count, newId);
2446
+ table.newToOldId.set(newId, count, oldId);
2447
+ if (detachLocation !== undefined) {
2448
+ table.detachLocations.set(oldId, count, detachLocation);
2449
+ }
2450
+ }
2451
+ exports.addNodeRename = addNodeRename;
2452
+ /**
2453
+ * Deletes any renames from `id`.
2454
+ */
2455
+ function deleteNodeRenameFrom(roots, id, count) {
2456
+ for (const entry of roots.oldToNewId.getAll(id, count)) {
2457
+ deleteNodeRenameEntry(roots, entry.start, entry.value, entry.length);
2458
+ }
2459
+ }
2460
+ /**
2461
+ * Deletes any renames to `id`.
2462
+ */
2463
+ function deleteNodeRenameTo(roots, id, count) {
2464
+ for (const entry of roots.newToOldId.getAll(id, count)) {
2465
+ deleteNodeRenameEntry(roots, entry.value, entry.start, entry.length);
2466
+ }
2467
+ }
2468
+ function appendNodeRename(composedTable, oldId, newId, count, change1Table, detachLocation) {
2469
+ let countToProcess = count;
2470
+ const rename1Entry = change1Table.newToOldId.getFirst(oldId, countToProcess);
2471
+ countToProcess = rename1Entry.length;
2472
+ if (rename1Entry.value !== undefined) {
2473
+ deleteNodeRenameFrom(composedTable, rename1Entry.value, countToProcess);
2474
+ }
2475
+ addNodeRename(composedTable, rename1Entry.value ?? oldId, newId, countToProcess, detachLocation);
2476
+ tryRemoveDetachLocation(composedTable, newId, countToProcess);
2477
+ if (countToProcess < count) {
2478
+ const countRemaining = count - countToProcess;
2479
+ appendNodeRename(composedTable, (0, index_js_2.offsetChangeAtomId)(oldId, countToProcess), (0, index_js_2.offsetChangeAtomId)(newId, countToProcess), countRemaining, change1Table, detachLocation);
2480
+ }
2481
+ }
2482
+ function tryRemoveDetachLocation(roots, rootId, count) {
2483
+ let countProcessed = count;
2484
+ const renameEntry = roots.oldToNewId.getFirst(rootId, countProcessed);
2485
+ countProcessed = renameEntry.length;
2486
+ const outputDetachEntry = roots.outputDetachLocations.getFirst(rootId, countProcessed);
2487
+ countProcessed = outputDetachEntry.length;
2488
+ const nodeChangeEntry = (0, changeAtomIdBTree_js_1.rangeQueryChangeAtomIdMap)(roots.nodeChanges, rootId, countProcessed);
2489
+ countProcessed = nodeChangeEntry.length;
2490
+ if (nodeChangeEntry.value === undefined &&
2491
+ renameEntry.value === undefined &&
2492
+ outputDetachEntry.value === undefined) {
2493
+ roots.detachLocations.delete(rootId, countProcessed);
2494
+ }
2495
+ const countRemaining = count - countProcessed;
2496
+ if (countRemaining > 0) {
2497
+ tryRemoveDetachLocation(roots, (0, index_js_2.offsetChangeAtomId)(rootId, countProcessed), countRemaining);
2498
+ }
2499
+ }
2500
+ /**
2501
+ * Deletes the entry renaming the ID range of length `count` from `oldId` to `newId`.
2502
+ * This function assumes that such an entry exists.
2503
+ */
2504
+ function deleteNodeRenameEntry(roots, oldId, newId, count) {
2505
+ roots.oldToNewId.delete(oldId, count);
2506
+ roots.newToOldId.delete(newId, count);
2507
+ }
2508
+ function replaceRootTableRevision(table, replacer, nodeAliases) {
2509
+ const oldToNewId = table.oldToNewId.mapEntries((id) => replacer.getUpdatedAtomId(id), (id) => replacer.getUpdatedAtomId(id));
2510
+ const newToOldId = table.newToOldId.mapEntries((id) => replacer.getUpdatedAtomId(id), (id) => replacer.getUpdatedAtomId(id));
2511
+ const nodeChanges = replaceIdMapRevisions(table.nodeChanges, replacer, (nodeId) => replacer.getUpdatedAtomId(normalizeNodeId(nodeId, nodeAliases)));
2512
+ const detachLocations = table.detachLocations.mapEntries((id) => replacer.getUpdatedAtomId(id), (fieldId) => replaceFieldIdRevision(normalizeFieldId(fieldId, nodeAliases), replacer));
2513
+ const outputDetachLocations = table.outputDetachLocations.mapEntries((id) => replacer.getUpdatedAtomId(id), (fieldId) => replaceFieldIdRevision(normalizeFieldId(fieldId, nodeAliases), replacer));
2514
+ return { oldToNewId, newToOldId, nodeChanges, detachLocations, outputDetachLocations };
2515
+ }
2516
+ function newDetachedEntryMap() {
2517
+ return new index_js_3.RangeMap(index_js_2.offsetChangeAtomId, index_js_2.subtractChangeAtomIds, offsetDetachedNodeEntry);
2518
+ }
2519
+ function offsetDetachedNodeEntry(entry, count) {
2520
+ (0, internal_1.assert)(count <= 1 || entry.nodeChange === undefined, "Cannot split an entry with a node change");
2521
+ return entry.detachId === undefined
2522
+ ? entry
2523
+ : { ...entry, detachId: (0, index_js_2.offsetChangeAtomId)(entry.detachId, count) };
2524
+ }
2525
+ function getFieldsWithRootMoves(roots, nodeAliases) {
2526
+ const fields = (0, index_js_3.newTupleBTree)();
2527
+ for (const { start: rootId, value: fieldId, length } of roots.detachLocations.entries()) {
2528
+ let isRootMoved = false;
2529
+ for (const renameEntry of roots.oldToNewId.getAll2(rootId, length)) {
2530
+ if (renameEntry.value !== undefined) {
2531
+ isRootMoved = true;
2532
+ }
2533
+ }
2534
+ for (const outputDetachEntry of roots.outputDetachLocations.getAll2(rootId, length)) {
2535
+ if (outputDetachEntry.value !== undefined) {
2536
+ isRootMoved = true;
2537
+ }
2538
+ }
2539
+ if (isRootMoved) {
2540
+ fields.set(fieldIdKeyFromFieldId(normalizeFieldId(fieldId, nodeAliases)), true);
2541
+ }
2542
+ }
2543
+ return fields;
2544
+ }
2545
+ function getFieldToRootChanges(roots, nodeAliases) {
2546
+ const fields = (0, index_js_3.newTupleBTree)();
2547
+ for (const rootIdKey of roots.nodeChanges.keys()) {
2548
+ const rootId = { revision: rootIdKey[0], localId: rootIdKey[1] };
2549
+ const detachLocation = roots.detachLocations.getFirst(rootId, 1).value;
2550
+ if (detachLocation !== undefined) {
2551
+ const fieldIdKey = fieldIdKeyFromFieldId(normalizeFieldId(detachLocation, nodeAliases));
2552
+ let rootsInField = fields.get(fieldIdKey);
2553
+ if (rootsInField === undefined) {
2554
+ rootsInField = [];
2555
+ fields.set(fieldIdKey, rootsInField);
2556
+ }
2557
+ rootsInField.push(rootId);
2558
+ }
2559
+ }
2560
+ return fields;
2561
+ }
2562
+ function muteRootChanges(roots) {
2563
+ return {
2564
+ oldToNewId: (0, index_js_2.newChangeAtomIdTransform)(),
2565
+ newToOldId: (0, index_js_2.newChangeAtomIdTransform)(),
2566
+ nodeChanges: (0, index_js_3.brand)(roots.nodeChanges.clone()),
2567
+ detachLocations: roots.detachLocations.clone(),
2568
+ outputDetachLocations: (0, index_js_2.newChangeAtomIdRangeMap)(),
2569
+ };
2570
+ }
2571
+ function validateChangeset(change, fieldKinds) {
2572
+ const unreachableNodes = (0, index_js_3.brand)(change.nodeToParent.clone());
2573
+ const unreachableCFKs = change.crossFieldKeys.clone();
2574
+ validateFieldChanges(fieldKinds, change, change.fieldChanges, undefined, unreachableNodes, unreachableCFKs);
2575
+ for (const [[revision, localId], node] of change.nodeChanges.entries()) {
2576
+ if (node.fieldChanges === undefined) {
2577
+ continue;
2578
+ }
2579
+ const nodeId = normalizeNodeId({ revision, localId }, change.nodeAliases);
2580
+ validateFieldChanges(fieldKinds, change, node.fieldChanges, nodeId, unreachableNodes, unreachableCFKs);
2581
+ }
2582
+ for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
2583
+ const detachId = { revision: detachIdKey[0], localId: detachIdKey[1] };
2584
+ const location = getNodeParent(change, nodeId);
2585
+ (0, internal_1.assert)((0, index_js_2.areEqualChangeAtomIdOpts)(location.root, detachId), "Inconsistent node location");
2586
+ const normalizedNodeId = normalizeNodeId(nodeId, change.nodeAliases);
2587
+ unreachableNodes.delete([normalizedNodeId.revision, normalizedNodeId.localId]);
2588
+ const fieldChanges = nodeChangeFromId(change.nodeChanges, change.nodeAliases, nodeId).fieldChanges;
2589
+ if (fieldChanges !== undefined) {
2590
+ validateFieldChanges(fieldKinds, change, fieldChanges, normalizedNodeId, unreachableNodes, unreachableCFKs);
2591
+ }
2592
+ }
2593
+ (0, internal_1.assert)(unreachableNodes.size === 0, "Unreachable nodes found");
2594
+ (0, internal_1.assert)(unreachableCFKs.entries().length === 0, "Unreachable cross-field keys found");
2595
+ }
2596
+ exports.validateChangeset = validateChangeset;
2597
+ /**
2598
+ * Asserts that each node has a correct entry in `change.nodeToParent`,
2599
+ * and each cross field key has a correct entry in `change.crossFieldKeys`.
2600
+ * @returns the number of children found.
2601
+ */
2602
+ function validateFieldChanges(fieldKinds, change, fieldChanges, nodeParent, unreachableNodes, unreachableCFKs) {
2603
+ for (const [field, fieldChange] of fieldChanges.entries()) {
2604
+ const fieldId = { nodeId: nodeParent, field };
2605
+ const handler = getChangeHandler(fieldKinds, fieldChange.fieldKind);
2606
+ for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
2607
+ const parentFieldId = getNodeParent(change, child);
2608
+ (0, internal_1.assert)(parentFieldId.field !== undefined && areEqualFieldIds(parentFieldId.field, fieldId), 0xa4e /* Inconsistent node parentage */);
2609
+ unreachableNodes.delete([child.revision, child.localId]);
2610
+ }
2611
+ for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
2612
+ const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
2613
+ (0, internal_1.assert)(fields.length > 0, "Unregistered cross-field key");
2614
+ for (const fieldFromLookup of fields) {
2615
+ (0, internal_1.assert)(areEqualFieldIds(fieldFromLookup, fieldId), 0xa4f /* Inconsistent cross field keys */);
2616
+ }
2617
+ unreachableCFKs.delete(keyRange.key, keyRange.count);
2618
+ }
2619
+ }
1716
2620
  }
1717
2621
  //# sourceMappingURL=modularChangeFamily.js.map