@fluidframework/tree 2.81.0-374083 → 2.81.1

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 (1522) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/api-report/tree.alpha.api.md +0 -1
  3. package/dist/codec/codec.d.ts +2 -2
  4. package/dist/codec/codec.d.ts.map +1 -1
  5. package/dist/codec/codec.js +8 -8
  6. package/dist/codec/codec.js.map +1 -1
  7. package/dist/codec/versioned/codec.d.ts +1 -1
  8. package/dist/codec/versioned/codec.d.ts.map +1 -1
  9. package/dist/codec/versioned/codec.js +12 -12
  10. package/dist/codec/versioned/codec.js.map +1 -1
  11. package/dist/core/change-family/changeFamily.d.ts +1 -4
  12. package/dist/core/change-family/changeFamily.d.ts.map +1 -1
  13. package/dist/core/change-family/changeFamily.js.map +1 -1
  14. package/dist/core/change-family/index.d.ts +1 -1
  15. package/dist/core/change-family/index.d.ts.map +1 -1
  16. package/dist/core/change-family/index.js.map +1 -1
  17. package/dist/core/index.d.ts +3 -3
  18. package/dist/core/index.d.ts.map +1 -1
  19. package/dist/core/index.js +4 -6
  20. package/dist/core/index.js.map +1 -1
  21. package/dist/core/rebase/changeRebaser.d.ts +1 -6
  22. package/dist/core/rebase/changeRebaser.d.ts.map +1 -1
  23. package/dist/core/rebase/changeRebaser.js.map +1 -1
  24. package/dist/core/rebase/index.d.ts +1 -1
  25. package/dist/core/rebase/index.d.ts.map +1 -1
  26. package/dist/core/rebase/index.js +1 -2
  27. package/dist/core/rebase/index.js.map +1 -1
  28. package/dist/core/rebase/types.d.ts +1 -2
  29. package/dist/core/rebase/types.d.ts.map +1 -1
  30. package/dist/core/rebase/types.js +1 -5
  31. package/dist/core/rebase/types.js.map +1 -1
  32. package/dist/core/rebase/utils.d.ts.map +1 -1
  33. package/dist/core/rebase/utils.js +7 -25
  34. package/dist/core/rebase/utils.js.map +1 -1
  35. package/dist/core/schema-stored/formatV2.d.ts.map +1 -1
  36. package/dist/core/schema-stored/formatV2.js +4 -4
  37. package/dist/core/schema-stored/formatV2.js.map +1 -1
  38. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  39. package/dist/core/tree/anchorSet.js +1 -1
  40. package/dist/core/tree/anchorSet.js.map +1 -1
  41. package/dist/core/tree/detachedFieldIndex.d.ts +0 -6
  42. package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
  43. package/dist/core/tree/detachedFieldIndex.js +0 -9
  44. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  45. package/dist/core/tree/detachedFieldIndexCodecCommon.d.ts +1 -1
  46. package/dist/core/tree/detachedFieldIndexCodecCommon.d.ts.map +1 -1
  47. package/dist/core/tree/detachedFieldIndexCodecCommon.js.map +1 -1
  48. package/dist/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
  49. package/dist/core/tree/detachedFieldIndexCodecV1.js +3 -3
  50. package/dist/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
  51. package/dist/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
  52. package/dist/core/tree/detachedFieldIndexCodecV2.js +2 -2
  53. package/dist/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
  54. package/dist/core/tree/detachedFieldIndexFormatV1.d.ts.map +1 -1
  55. package/dist/core/tree/detachedFieldIndexFormatV1.js +3 -3
  56. package/dist/core/tree/detachedFieldIndexFormatV1.js.map +1 -1
  57. package/dist/core/tree/detachedFieldIndexFormatV2.d.ts.map +1 -1
  58. package/dist/core/tree/detachedFieldIndexFormatV2.js +4 -4
  59. package/dist/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
  60. package/dist/core/tree/index.d.ts +1 -1
  61. package/dist/core/tree/index.d.ts.map +1 -1
  62. package/dist/core/tree/index.js +3 -4
  63. package/dist/core/tree/index.js.map +1 -1
  64. package/dist/core/tree/pathTree.d.ts +3 -11
  65. package/dist/core/tree/pathTree.d.ts.map +1 -1
  66. package/dist/core/tree/pathTree.js +2 -14
  67. package/dist/core/tree/pathTree.js.map +1 -1
  68. package/dist/core/tree/visitDelta.d.ts +1 -1
  69. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  70. package/dist/core/tree/visitDelta.js.map +1 -1
  71. package/dist/core/tree/visitorUtils.d.ts.map +1 -1
  72. package/dist/core/tree/visitorUtils.js +1 -1
  73. package/dist/core/tree/visitorUtils.js.map +1 -1
  74. package/dist/feature-libraries/changeAtomIdBTree.d.ts +3 -4
  75. package/dist/feature-libraries/changeAtomIdBTree.d.ts.map +1 -1
  76. package/dist/feature-libraries/changeAtomIdBTree.js +2 -16
  77. package/dist/feature-libraries/changeAtomIdBTree.js.map +1 -1
  78. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  79. package/dist/feature-libraries/chunked-forest/basicChunk.js +0 -7
  80. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  81. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +1 -1
  82. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  83. package/dist/feature-libraries/chunked-forest/chunkTree.js +1 -4
  84. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  85. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +1 -1
  86. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  87. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  88. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +1 -1
  89. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  90. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  91. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.d.ts +1 -1
  92. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.d.ts.map +1 -1
  93. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  94. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +1 -1
  95. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  96. package/dist/feature-libraries/chunked-forest/codec/codecs.js +1 -1
  97. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  98. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +1 -1
  99. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  100. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  101. package/dist/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  102. package/dist/feature-libraries/chunked-forest/codec/format.js +1 -1
  103. package/dist/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  104. package/dist/feature-libraries/chunked-forest/codec/formatGeneric.d.ts.map +1 -1
  105. package/dist/feature-libraries/chunked-forest/codec/formatGeneric.js.map +1 -1
  106. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +1 -1
  107. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  108. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +2 -2
  109. package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  110. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +44 -93
  111. package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  112. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +78 -245
  113. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  114. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +11 -53
  115. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  116. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +25 -75
  117. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  118. package/dist/feature-libraries/default-schema/index.d.ts +2 -3
  119. package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
  120. package/dist/feature-libraries/default-schema/index.js +2 -5
  121. package/dist/feature-libraries/default-schema/index.js.map +1 -1
  122. package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts +6 -7
  123. package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
  124. package/dist/feature-libraries/default-schema/mappedEditBuilder.js +0 -15
  125. package/dist/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
  126. package/dist/feature-libraries/deltaUtils.d.ts +0 -1
  127. package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
  128. package/dist/feature-libraries/deltaUtils.js +1 -6
  129. package/dist/feature-libraries/deltaUtils.js.map +1 -1
  130. package/dist/feature-libraries/fieldKindIdentifiers.d.ts +9 -0
  131. package/dist/feature-libraries/fieldKindIdentifiers.d.ts.map +1 -0
  132. package/dist/feature-libraries/fieldKindIdentifiers.js +16 -0
  133. package/dist/feature-libraries/fieldKindIdentifiers.js.map +1 -0
  134. package/dist/feature-libraries/flex-tree/context.d.ts +0 -9
  135. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  136. package/dist/feature-libraries/flex-tree/context.js +0 -6
  137. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  138. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
  139. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  140. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  141. package/dist/feature-libraries/flex-tree/lazyField.d.ts +7 -8
  142. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  143. package/dist/feature-libraries/flex-tree/lazyField.js +17 -48
  144. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  145. package/dist/feature-libraries/flex-tree/observer.d.ts +1 -1
  146. package/dist/feature-libraries/flex-tree/observer.d.ts.map +1 -1
  147. package/dist/feature-libraries/flex-tree/observer.js.map +1 -1
  148. package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  149. package/dist/feature-libraries/forest-summary/codec.js +1 -1
  150. package/dist/feature-libraries/forest-summary/codec.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 -3
  153. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  154. package/dist/feature-libraries/forest-summary/formatV1.d.ts.map +1 -1
  155. package/dist/feature-libraries/forest-summary/formatV1.js.map +1 -1
  156. package/dist/feature-libraries/forest-summary/formatV2.d.ts.map +1 -1
  157. package/dist/feature-libraries/forest-summary/formatV2.js.map +1 -1
  158. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +4 -4
  159. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  160. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +2 -2
  161. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  162. package/dist/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -1
  163. package/dist/feature-libraries/forest-summary/summaryTypes.js.map +1 -1
  164. package/dist/feature-libraries/index.d.ts +3 -3
  165. package/dist/feature-libraries/index.d.ts.map +1 -1
  166. package/dist/feature-libraries/index.js +3 -8
  167. package/dist/feature-libraries/index.js.map +1 -1
  168. package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
  169. package/dist/feature-libraries/mapTreeCursor.js +0 -1
  170. package/dist/feature-libraries/mapTreeCursor.js.map +1 -1
  171. package/dist/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
  172. package/dist/feature-libraries/mitigatedChangeFamily.js +2 -2
  173. package/dist/feature-libraries/mitigatedChangeFamily.js.map +1 -1
  174. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +21 -97
  175. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  176. package/dist/feature-libraries/modular-schema/crossFieldQueries.js +7 -4
  177. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  178. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +51 -20
  179. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  180. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  181. package/dist/feature-libraries/modular-schema/fieldKindConfiguration.d.ts.map +1 -1
  182. package/dist/feature-libraries/modular-schema/fieldKindConfiguration.js.map +1 -1
  183. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts +1 -1
  184. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  185. package/dist/feature-libraries/modular-schema/genericFieldKind.js +11 -5
  186. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  187. package/dist/feature-libraries/modular-schema/index.d.ts +4 -4
  188. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  189. package/dist/feature-libraries/modular-schema/index.js +2 -2
  190. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  191. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +28 -11
  192. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
  193. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +162 -254
  194. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
  195. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -1
  196. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js +1 -1
  197. package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -1
  198. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  199. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +1 -8
  200. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  201. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +21 -49
  202. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  203. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +460 -1325
  204. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  205. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
  206. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
  207. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +8 -44
  208. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  209. package/dist/feature-libraries/modular-schema/modularChangeTypes.js +3 -3
  210. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  211. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  212. package/dist/feature-libraries/object-forest/objectForest.js +2 -2
  213. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  214. package/dist/feature-libraries/optional-field/index.d.ts +2 -2
  215. package/dist/feature-libraries/optional-field/index.d.ts.map +1 -1
  216. package/dist/feature-libraries/optional-field/index.js +4 -7
  217. package/dist/feature-libraries/optional-field/index.js.map +1 -1
  218. package/dist/feature-libraries/optional-field/optionalField.d.ts +34 -5
  219. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  220. package/dist/feature-libraries/optional-field/optionalField.js +455 -221
  221. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  222. package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +33 -24
  223. package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
  224. package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
  225. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
  226. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
  227. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js +28 -57
  228. package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
  229. package/dist/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
  230. package/dist/feature-libraries/optional-field/optionalFieldCodecs.js +1 -5
  231. package/dist/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
  232. package/dist/feature-libraries/optional-field/requiredField.d.ts +36 -0
  233. package/dist/feature-libraries/optional-field/requiredField.d.ts.map +1 -0
  234. package/dist/feature-libraries/optional-field/requiredField.js +27 -0
  235. package/dist/feature-libraries/optional-field/requiredField.js.map +1 -0
  236. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.d.ts +1 -1
  237. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
  238. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js +7 -7
  239. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
  240. package/dist/feature-libraries/schema-edits/schemaChangeFormat.d.ts.map +1 -1
  241. package/dist/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
  242. package/dist/feature-libraries/schemaChecker.d.ts.map +1 -1
  243. package/dist/feature-libraries/schemaChecker.js +1 -1
  244. package/dist/feature-libraries/schemaChecker.js.map +1 -1
  245. package/dist/feature-libraries/sequence-field/compose.d.ts +7 -6
  246. package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
  247. package/dist/feature-libraries/sequence-field/compose.js +259 -83
  248. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  249. package/dist/feature-libraries/sequence-field/helperTypes.d.ts +10 -14
  250. package/dist/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
  251. package/dist/feature-libraries/sequence-field/helperTypes.js.map +1 -1
  252. package/dist/feature-libraries/sequence-field/index.d.ts +2 -13
  253. package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
  254. package/dist/feature-libraries/sequence-field/index.js +3 -28
  255. package/dist/feature-libraries/sequence-field/index.js.map +1 -1
  256. package/dist/feature-libraries/sequence-field/invert.d.ts +3 -3
  257. package/dist/feature-libraries/sequence-field/invert.d.ts.map +1 -1
  258. package/dist/feature-libraries/sequence-field/invert.js +167 -65
  259. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  260. package/dist/feature-libraries/sequence-field/markQueue.d.ts +2 -2
  261. package/dist/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
  262. package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
  263. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +56 -4
  264. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  265. package/dist/feature-libraries/sequence-field/moveEffectTable.js +90 -7
  266. package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  267. package/dist/feature-libraries/sequence-field/rebase.d.ts +3 -3
  268. package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  269. package/dist/feature-libraries/sequence-field/rebase.js +114 -107
  270. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  271. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +9 -0
  272. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +1 -0
  273. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js +50 -0
  274. package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js.map +1 -0
  275. package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
  276. package/dist/feature-libraries/sequence-field/replaceRevisions.js +31 -18
  277. package/dist/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
  278. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  279. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -0
  280. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  281. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +4 -22
  282. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
  283. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +187 -365
  284. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  285. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
  286. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js +62 -20
  287. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
  288. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
  289. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
  290. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
  291. package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
  292. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  293. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  294. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +109 -14
  295. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  296. package/dist/feature-libraries/sequence-field/sequenceKind.d.ts +16 -0
  297. package/dist/feature-libraries/sequence-field/sequenceKind.d.ts.map +1 -0
  298. package/dist/feature-libraries/sequence-field/sequenceKind.js +24 -0
  299. package/dist/feature-libraries/sequence-field/sequenceKind.js.map +1 -0
  300. package/dist/feature-libraries/sequence-field/types.d.ts +59 -30
  301. package/dist/feature-libraries/sequence-field/types.d.ts.map +1 -1
  302. package/dist/feature-libraries/sequence-field/types.js.map +1 -1
  303. package/dist/feature-libraries/sequence-field/utils.d.ts +24 -15
  304. package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  305. package/dist/feature-libraries/sequence-field/utils.js +305 -116
  306. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  307. package/dist/index.d.ts +1 -1
  308. package/dist/index.d.ts.map +1 -1
  309. package/dist/index.js +2 -1
  310. package/dist/index.js.map +1 -1
  311. package/dist/packageVersion.d.ts +1 -1
  312. package/dist/packageVersion.d.ts.map +1 -1
  313. package/dist/packageVersion.js +1 -1
  314. package/dist/packageVersion.js.map +1 -1
  315. package/dist/shared-tree/independentView.d.ts.map +1 -1
  316. package/dist/shared-tree/independentView.js +7 -7
  317. package/dist/shared-tree/independentView.js.map +1 -1
  318. package/dist/shared-tree/index.d.ts +1 -1
  319. package/dist/shared-tree/index.d.ts.map +1 -1
  320. package/dist/shared-tree/index.js.map +1 -1
  321. package/dist/shared-tree/schematizeTree.d.ts +4 -4
  322. package/dist/shared-tree/schematizeTree.d.ts.map +1 -1
  323. package/dist/shared-tree/schematizeTree.js +1 -2
  324. package/dist/shared-tree/schematizeTree.js.map +1 -1
  325. package/dist/shared-tree/schematizingTreeView.d.ts +5 -1
  326. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  327. package/dist/shared-tree/schematizingTreeView.js +39 -40
  328. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  329. package/dist/shared-tree/sharedTree.d.ts +5 -11
  330. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  331. package/dist/shared-tree/sharedTree.js +5 -43
  332. package/dist/shared-tree/sharedTree.js.map +1 -1
  333. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
  334. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  335. package/dist/shared-tree/sharedTreeChangeCodecs.js +0 -1
  336. package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  337. package/dist/shared-tree/sharedTreeChangeEnricher.d.ts +31 -24
  338. package/dist/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
  339. package/dist/shared-tree/sharedTreeChangeEnricher.js +75 -58
  340. package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  341. package/dist/shared-tree/sharedTreeChangeFamily.d.ts +5 -5
  342. package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  343. package/dist/shared-tree/sharedTreeChangeFamily.js +4 -10
  344. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  345. package/dist/shared-tree/sharedTreeEditBuilder.d.ts +6 -16
  346. package/dist/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
  347. package/dist/shared-tree/sharedTreeEditBuilder.js +7 -14
  348. package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  349. package/dist/shared-tree/tree.d.ts.map +1 -1
  350. package/dist/shared-tree/tree.js +14 -14
  351. package/dist/shared-tree/tree.js.map +1 -1
  352. package/dist/shared-tree/treeAlpha.d.ts +1 -1
  353. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  354. package/dist/shared-tree/treeAlpha.js +77 -77
  355. package/dist/shared-tree/treeAlpha.js.map +1 -1
  356. package/dist/shared-tree/treeCheckout.d.ts +29 -13
  357. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  358. package/dist/shared-tree/treeCheckout.js +80 -79
  359. package/dist/shared-tree/treeCheckout.js.map +1 -1
  360. package/dist/shared-tree-core/branch.d.ts +3 -4
  361. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  362. package/dist/shared-tree-core/branch.js +3 -4
  363. package/dist/shared-tree-core/branch.js.map +1 -1
  364. package/dist/shared-tree-core/branchCommitEnricher.d.ts +18 -31
  365. package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  366. package/dist/shared-tree-core/branchCommitEnricher.js +24 -76
  367. package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
  368. package/dist/shared-tree-core/branchIdCodec.d.ts.map +1 -1
  369. package/dist/shared-tree-core/branchIdCodec.js.map +1 -1
  370. package/dist/shared-tree-core/changeEnricher.d.ts +8 -43
  371. package/dist/shared-tree-core/changeEnricher.d.ts.map +1 -1
  372. package/dist/shared-tree-core/changeEnricher.js +0 -13
  373. package/dist/shared-tree-core/changeEnricher.js.map +1 -1
  374. package/dist/shared-tree-core/defaultResubmitMachine.d.ts +4 -12
  375. package/dist/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
  376. package/dist/shared-tree-core/defaultResubmitMachine.js +26 -36
  377. package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  378. package/dist/shared-tree-core/editManager.d.ts +3 -3
  379. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  380. package/dist/shared-tree-core/editManager.js +11 -11
  381. package/dist/shared-tree-core/editManager.js.map +1 -1
  382. package/dist/shared-tree-core/editManagerCodecs.d.ts +1 -5
  383. package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  384. package/dist/shared-tree-core/editManagerCodecs.js +2 -10
  385. package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
  386. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +1 -1
  387. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  388. package/dist/shared-tree-core/editManagerCodecsCommons.js +1 -2
  389. package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  390. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  391. package/dist/shared-tree-core/editManagerCodecsV1toV4.js +1 -1
  392. package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  393. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  394. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js +1 -1
  395. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  396. package/dist/shared-tree-core/editManagerFormatCommons.d.ts +0 -1
  397. package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
  398. package/dist/shared-tree-core/editManagerFormatCommons.js +0 -6
  399. package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  400. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
  401. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
  402. package/dist/shared-tree-core/editManagerFormatV1toV4.js +0 -1
  403. package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  404. package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts +1 -1
  405. package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -1
  406. package/dist/shared-tree-core/editManagerFormatVSharedBranches.js +1 -1
  407. package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
  408. package/dist/shared-tree-core/index.d.ts +4 -4
  409. package/dist/shared-tree-core/index.d.ts.map +1 -1
  410. package/dist/shared-tree-core/index.js +1 -5
  411. package/dist/shared-tree-core/index.js.map +1 -1
  412. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts +2 -2
  413. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  414. package/dist/shared-tree-core/messageCodecV1ToV4.js +1 -1
  415. package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  416. package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts +1 -1
  417. package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  418. package/dist/shared-tree-core/messageCodecVSharedBranches.js +2 -2
  419. package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  420. package/dist/shared-tree-core/messageCodecs.d.ts +2 -6
  421. package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
  422. package/dist/shared-tree-core/messageCodecs.js +2 -10
  423. package/dist/shared-tree-core/messageCodecs.js.map +1 -1
  424. package/dist/shared-tree-core/messageFormat.d.ts +0 -1
  425. package/dist/shared-tree-core/messageFormat.d.ts.map +1 -1
  426. package/dist/shared-tree-core/messageFormat.js +0 -6
  427. package/dist/shared-tree-core/messageFormat.js.map +1 -1
  428. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +2 -2
  429. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
  430. package/dist/shared-tree-core/messageFormatV1ToV4.js +0 -1
  431. package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  432. package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -1
  433. package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
  434. package/dist/shared-tree-core/messageTypes.d.ts.map +1 -1
  435. package/dist/shared-tree-core/messageTypes.js.map +1 -1
  436. package/dist/shared-tree-core/sharedTreeCore.d.ts +8 -5
  437. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  438. package/dist/shared-tree-core/sharedTreeCore.js +14 -14
  439. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  440. package/dist/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
  441. package/dist/shared-tree-core/versionedSummarizer.js +1 -1
  442. package/dist/shared-tree-core/versionedSummarizer.js.map +1 -1
  443. package/dist/simple-tree/api/configuration.d.ts +2 -2
  444. package/dist/simple-tree/api/configuration.d.ts.map +1 -1
  445. package/dist/simple-tree/api/configuration.js +14 -14
  446. package/dist/simple-tree/api/configuration.js.map +1 -1
  447. package/dist/simple-tree/api/create.d.ts +1 -1
  448. package/dist/simple-tree/api/create.d.ts.map +1 -1
  449. package/dist/simple-tree/api/create.js +7 -7
  450. package/dist/simple-tree/api/create.js.map +1 -1
  451. package/dist/simple-tree/api/dirtyIndex.d.ts +1 -1
  452. package/dist/simple-tree/api/dirtyIndex.d.ts.map +1 -1
  453. package/dist/simple-tree/api/dirtyIndex.js.map +1 -1
  454. package/dist/simple-tree/api/discrepancies.d.ts.map +1 -1
  455. package/dist/simple-tree/api/discrepancies.js +23 -23
  456. package/dist/simple-tree/api/discrepancies.js.map +1 -1
  457. package/dist/simple-tree/api/getJsonSchema.d.ts +1 -1
  458. package/dist/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  459. package/dist/simple-tree/api/getJsonSchema.js +1 -1
  460. package/dist/simple-tree/api/getJsonSchema.js.map +1 -1
  461. package/dist/simple-tree/api/identifierIndex.d.ts +2 -2
  462. package/dist/simple-tree/api/identifierIndex.d.ts.map +1 -1
  463. package/dist/simple-tree/api/identifierIndex.js.map +1 -1
  464. package/dist/simple-tree/api/incrementalAllowedTypes.d.ts +1 -1
  465. package/dist/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -1
  466. package/dist/simple-tree/api/incrementalAllowedTypes.js +6 -6
  467. package/dist/simple-tree/api/incrementalAllowedTypes.js.map +1 -1
  468. package/dist/simple-tree/api/schemaCompatibilityTester.d.ts +1 -1
  469. package/dist/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
  470. package/dist/simple-tree/api/schemaCompatibilityTester.js +1 -1
  471. package/dist/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
  472. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +2 -2
  473. package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  474. package/dist/simple-tree/api/schemaCreationUtilities.js +7 -7
  475. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  476. package/dist/simple-tree/api/schemaFactory.d.ts +2 -2
  477. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  478. package/dist/simple-tree/api/schemaFactory.js +7 -7
  479. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  480. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +6 -6
  481. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  482. package/dist/simple-tree/api/schemaFactoryAlpha.js +1 -1
  483. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  484. package/dist/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
  485. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  486. package/dist/simple-tree/api/schemaFactoryBeta.js +1 -0
  487. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  488. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
  489. package/dist/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  490. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  491. package/dist/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
  492. package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
  493. package/dist/simple-tree/api/schemaStatics.d.ts.map +1 -1
  494. package/dist/simple-tree/api/schemaStatics.js.map +1 -1
  495. package/dist/simple-tree/api/simpleSchemaCodec.d.ts +1 -1
  496. package/dist/simple-tree/api/simpleSchemaCodec.d.ts.map +1 -1
  497. package/dist/simple-tree/api/simpleSchemaCodec.js +17 -17
  498. package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
  499. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +2 -2
  500. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  501. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +2 -2
  502. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  503. package/dist/simple-tree/api/simpleTreeIndex.d.ts +1 -1
  504. package/dist/simple-tree/api/simpleTreeIndex.d.ts.map +1 -1
  505. package/dist/simple-tree/api/simpleTreeIndex.js +1 -1
  506. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  507. package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
  508. package/dist/simple-tree/api/snapshotCompatibilityChecker.js +14 -14
  509. package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  510. package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
  511. package/dist/simple-tree/api/storedSchema.js.map +1 -1
  512. package/dist/simple-tree/api/tree.d.ts +2 -2
  513. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  514. package/dist/simple-tree/api/tree.js.map +1 -1
  515. package/dist/simple-tree/api/treeBeta.d.ts +1 -1
  516. package/dist/simple-tree/api/treeBeta.d.ts.map +1 -1
  517. package/dist/simple-tree/api/treeBeta.js +2 -2
  518. package/dist/simple-tree/api/treeBeta.js.map +1 -1
  519. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  520. package/dist/simple-tree/api/treeNodeApi.js +4 -4
  521. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  522. package/dist/simple-tree/api/typesUnsafe.d.ts +1 -1
  523. package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  524. package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
  525. package/dist/simple-tree/api/verboseTree.d.ts +1 -1
  526. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  527. package/dist/simple-tree/api/verboseTree.js +22 -22
  528. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  529. package/dist/simple-tree/core/allowedTypes.d.ts +1 -1
  530. package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
  531. package/dist/simple-tree/core/allowedTypes.js +7 -7
  532. package/dist/simple-tree/core/allowedTypes.js.map +1 -1
  533. package/dist/simple-tree/core/context.d.ts.map +1 -1
  534. package/dist/simple-tree/core/context.js.map +1 -1
  535. package/dist/simple-tree/core/treeNode.d.ts.map +1 -1
  536. package/dist/simple-tree/core/treeNode.js +1 -1
  537. package/dist/simple-tree/core/treeNode.js.map +1 -1
  538. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  539. package/dist/simple-tree/core/treeNodeKernel.js +1 -3
  540. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  541. package/dist/simple-tree/core/treeNodeSchema.d.ts +5 -5
  542. package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  543. package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
  544. package/dist/simple-tree/core/treeNodeValid.d.ts +3 -3
  545. package/dist/simple-tree/core/treeNodeValid.d.ts.map +1 -1
  546. package/dist/simple-tree/core/treeNodeValid.js +2 -2
  547. package/dist/simple-tree/core/treeNodeValid.js.map +1 -1
  548. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +16 -16
  549. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  550. package/dist/simple-tree/core/unhydratedFlexTree.js +8 -59
  551. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  552. package/dist/simple-tree/core/withType.d.ts.map +1 -1
  553. package/dist/simple-tree/core/withType.js.map +1 -1
  554. package/dist/simple-tree/createContext.d.ts.map +1 -1
  555. package/dist/simple-tree/createContext.js.map +1 -1
  556. package/dist/simple-tree/fieldSchema.d.ts +5 -5
  557. package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
  558. package/dist/simple-tree/fieldSchema.js.map +1 -1
  559. package/dist/simple-tree/index.d.ts +2 -2
  560. package/dist/simple-tree/index.d.ts.map +1 -1
  561. package/dist/simple-tree/index.js +1 -1
  562. package/dist/simple-tree/index.js.map +1 -1
  563. package/dist/simple-tree/leafNodeSchema.d.ts +1 -1
  564. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  565. package/dist/simple-tree/leafNodeSchema.js +15 -15
  566. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  567. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts +1 -1
  568. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  569. package/dist/simple-tree/node-kinds/array/arrayNode.js +47 -49
  570. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  571. package/dist/simple-tree/node-kinds/array/arrayNodeTypes.d.ts +1 -1
  572. package/dist/simple-tree/node-kinds/array/arrayNodeTypes.d.ts.map +1 -1
  573. package/dist/simple-tree/node-kinds/array/arrayNodeTypes.js.map +1 -1
  574. package/dist/simple-tree/node-kinds/common.d.ts.map +1 -1
  575. package/dist/simple-tree/node-kinds/common.js +1 -1
  576. package/dist/simple-tree/node-kinds/common.js.map +1 -1
  577. package/dist/simple-tree/node-kinds/map/mapNode.d.ts +2 -2
  578. package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  579. package/dist/simple-tree/node-kinds/map/mapNode.js +26 -26
  580. package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  581. package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts +1 -1
  582. package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
  583. package/dist/simple-tree/node-kinds/map/mapNodeTypes.js.map +1 -1
  584. package/dist/simple-tree/node-kinds/object/objectNode.d.ts +2 -2
  585. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  586. package/dist/simple-tree/node-kinds/object/objectNode.js +28 -28
  587. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  588. package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts +3 -3
  589. package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
  590. package/dist/simple-tree/node-kinds/object/objectNodeTypes.js.map +1 -1
  591. package/dist/simple-tree/node-kinds/record/recordNode.d.ts +1 -1
  592. package/dist/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
  593. package/dist/simple-tree/node-kinds/record/recordNode.js +36 -38
  594. package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  595. package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts +1 -1
  596. package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts.map +1 -1
  597. package/dist/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
  598. package/dist/simple-tree/prepareForInsertion.d.ts +47 -54
  599. package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
  600. package/dist/simple-tree/prepareForInsertion.js +128 -186
  601. package/dist/simple-tree/prepareForInsertion.js.map +1 -1
  602. package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
  603. package/dist/simple-tree/simpleSchema.js.map +1 -1
  604. package/dist/simple-tree/treeSchema.d.ts.map +1 -1
  605. package/dist/simple-tree/treeSchema.js.map +1 -1
  606. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +4 -13
  607. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  608. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +22 -40
  609. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  610. package/dist/tableSchema.d.ts.map +1 -1
  611. package/dist/tableSchema.js +22 -21
  612. package/dist/tableSchema.js.map +1 -1
  613. package/dist/text/index.d.ts +1 -0
  614. package/dist/text/index.d.ts.map +1 -1
  615. package/dist/text/index.js +3 -1
  616. package/dist/text/index.js.map +1 -1
  617. package/dist/text/textDomain.d.ts +8 -0
  618. package/dist/text/textDomain.d.ts.map +1 -1
  619. package/dist/text/textDomain.js +2 -1
  620. package/dist/text/textDomain.js.map +1 -1
  621. package/dist/text/textDomainFormatted.d.ts +572 -0
  622. package/dist/text/textDomainFormatted.d.ts.map +1 -0
  623. package/dist/text/textDomainFormatted.js +183 -0
  624. package/dist/text/textDomainFormatted.js.map +1 -0
  625. package/dist/treeFactory.d.ts.map +1 -1
  626. package/dist/treeFactory.js +11 -21
  627. package/dist/treeFactory.js.map +1 -1
  628. package/dist/util/bTreeUtils.d.ts.map +1 -1
  629. package/dist/util/bTreeUtils.js +1 -1
  630. package/dist/util/bTreeUtils.js.map +1 -1
  631. package/dist/util/index.d.ts +1 -1
  632. package/dist/util/index.d.ts.map +1 -1
  633. package/dist/util/index.js +1 -2
  634. package/dist/util/index.js.map +1 -1
  635. package/dist/util/rangeMap.d.ts +12 -24
  636. package/dist/util/rangeMap.d.ts.map +1 -1
  637. package/dist/util/rangeMap.js +6 -46
  638. package/dist/util/rangeMap.js.map +1 -1
  639. package/dist/util/readSnapshotBlob.d.ts +1 -1
  640. package/dist/util/readSnapshotBlob.d.ts.map +1 -1
  641. package/dist/util/readSnapshotBlob.js.map +1 -1
  642. package/docs/main/sequence-field/move-composition.md +46 -0
  643. package/eslint.config.mts +4 -4
  644. package/lib/codec/codec.d.ts +2 -2
  645. package/lib/codec/codec.d.ts.map +1 -1
  646. package/lib/codec/codec.js +1 -1
  647. package/lib/codec/codec.js.map +1 -1
  648. package/lib/codec/versioned/codec.d.ts +1 -1
  649. package/lib/codec/versioned/codec.d.ts.map +1 -1
  650. package/lib/codec/versioned/codec.js +2 -2
  651. package/lib/codec/versioned/codec.js.map +1 -1
  652. package/lib/core/change-family/changeFamily.d.ts +1 -4
  653. package/lib/core/change-family/changeFamily.d.ts.map +1 -1
  654. package/lib/core/change-family/changeFamily.js.map +1 -1
  655. package/lib/core/change-family/index.d.ts +1 -1
  656. package/lib/core/change-family/index.d.ts.map +1 -1
  657. package/lib/core/change-family/index.js.map +1 -1
  658. package/lib/core/index.d.ts +3 -3
  659. package/lib/core/index.d.ts.map +1 -1
  660. package/lib/core/index.js +2 -2
  661. package/lib/core/index.js.map +1 -1
  662. package/lib/core/rebase/changeRebaser.d.ts +1 -6
  663. package/lib/core/rebase/changeRebaser.d.ts.map +1 -1
  664. package/lib/core/rebase/changeRebaser.js.map +1 -1
  665. package/lib/core/rebase/index.d.ts +1 -1
  666. package/lib/core/rebase/index.d.ts.map +1 -1
  667. package/lib/core/rebase/index.js +1 -1
  668. package/lib/core/rebase/index.js.map +1 -1
  669. package/lib/core/rebase/types.d.ts +1 -2
  670. package/lib/core/rebase/types.d.ts.map +1 -1
  671. package/lib/core/rebase/types.js +0 -3
  672. package/lib/core/rebase/types.js.map +1 -1
  673. package/lib/core/rebase/utils.d.ts.map +1 -1
  674. package/lib/core/rebase/utils.js +7 -25
  675. package/lib/core/rebase/utils.js.map +1 -1
  676. package/lib/core/schema-stored/formatV2.d.ts.map +1 -1
  677. package/lib/core/schema-stored/formatV2.js +1 -1
  678. package/lib/core/schema-stored/formatV2.js.map +1 -1
  679. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  680. package/lib/core/tree/anchorSet.js +1 -1
  681. package/lib/core/tree/anchorSet.js.map +1 -1
  682. package/lib/core/tree/detachedFieldIndex.d.ts +0 -6
  683. package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
  684. package/lib/core/tree/detachedFieldIndex.js +1 -10
  685. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  686. package/lib/core/tree/detachedFieldIndexCodecCommon.d.ts +1 -1
  687. package/lib/core/tree/detachedFieldIndexCodecCommon.d.ts.map +1 -1
  688. package/lib/core/tree/detachedFieldIndexCodecCommon.js.map +1 -1
  689. package/lib/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
  690. package/lib/core/tree/detachedFieldIndexCodecV1.js +1 -1
  691. package/lib/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
  692. package/lib/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
  693. package/lib/core/tree/detachedFieldIndexCodecV2.js +2 -2
  694. package/lib/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
  695. package/lib/core/tree/detachedFieldIndexFormatV1.d.ts.map +1 -1
  696. package/lib/core/tree/detachedFieldIndexFormatV1.js +2 -2
  697. package/lib/core/tree/detachedFieldIndexFormatV1.js.map +1 -1
  698. package/lib/core/tree/detachedFieldIndexFormatV2.d.ts.map +1 -1
  699. package/lib/core/tree/detachedFieldIndexFormatV2.js +2 -2
  700. package/lib/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
  701. package/lib/core/tree/index.d.ts +1 -1
  702. package/lib/core/tree/index.d.ts.map +1 -1
  703. package/lib/core/tree/index.js +1 -1
  704. package/lib/core/tree/index.js.map +1 -1
  705. package/lib/core/tree/pathTree.d.ts +3 -11
  706. package/lib/core/tree/pathTree.d.ts.map +1 -1
  707. package/lib/core/tree/pathTree.js +1 -12
  708. package/lib/core/tree/pathTree.js.map +1 -1
  709. package/lib/core/tree/visitDelta.d.ts +1 -1
  710. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  711. package/lib/core/tree/visitDelta.js.map +1 -1
  712. package/lib/core/tree/visitorUtils.d.ts.map +1 -1
  713. package/lib/core/tree/visitorUtils.js +1 -1
  714. package/lib/core/tree/visitorUtils.js.map +1 -1
  715. package/lib/feature-libraries/changeAtomIdBTree.d.ts +3 -4
  716. package/lib/feature-libraries/changeAtomIdBTree.d.ts.map +1 -1
  717. package/lib/feature-libraries/changeAtomIdBTree.js +1 -14
  718. package/lib/feature-libraries/changeAtomIdBTree.js.map +1 -1
  719. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  720. package/lib/feature-libraries/chunked-forest/basicChunk.js +1 -8
  721. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  722. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +1 -1
  723. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  724. package/lib/feature-libraries/chunked-forest/chunkTree.js +1 -4
  725. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  726. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +1 -1
  727. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  728. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  729. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +1 -1
  730. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  731. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  732. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.d.ts +1 -1
  733. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.d.ts.map +1 -1
  734. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  735. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +1 -1
  736. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  737. package/lib/feature-libraries/chunked-forest/codec/codecs.js +1 -1
  738. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  739. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +1 -1
  740. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  741. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  742. package/lib/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  743. package/lib/feature-libraries/chunked-forest/codec/format.js +1 -1
  744. package/lib/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  745. package/lib/feature-libraries/chunked-forest/codec/formatGeneric.d.ts.map +1 -1
  746. package/lib/feature-libraries/chunked-forest/codec/formatGeneric.js.map +1 -1
  747. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +1 -1
  748. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
  749. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +2 -2
  750. package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
  751. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +44 -93
  752. package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
  753. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +73 -237
  754. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  755. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +11 -53
  756. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  757. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +6 -56
  758. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  759. package/lib/feature-libraries/default-schema/index.d.ts +2 -3
  760. package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
  761. package/lib/feature-libraries/default-schema/index.js +1 -2
  762. package/lib/feature-libraries/default-schema/index.js.map +1 -1
  763. package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts +6 -7
  764. package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
  765. package/lib/feature-libraries/default-schema/mappedEditBuilder.js +0 -15
  766. package/lib/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
  767. package/lib/feature-libraries/deltaUtils.d.ts +0 -1
  768. package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
  769. package/lib/feature-libraries/deltaUtils.js +1 -5
  770. package/lib/feature-libraries/deltaUtils.js.map +1 -1
  771. package/lib/feature-libraries/fieldKindIdentifiers.d.ts +9 -0
  772. package/lib/feature-libraries/fieldKindIdentifiers.d.ts.map +1 -0
  773. package/lib/feature-libraries/fieldKindIdentifiers.js +13 -0
  774. package/lib/feature-libraries/fieldKindIdentifiers.js.map +1 -0
  775. package/lib/feature-libraries/flex-tree/context.d.ts +0 -9
  776. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  777. package/lib/feature-libraries/flex-tree/context.js +0 -6
  778. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  779. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
  780. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  781. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  782. package/lib/feature-libraries/flex-tree/lazyField.d.ts +7 -8
  783. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  784. package/lib/feature-libraries/flex-tree/lazyField.js +11 -42
  785. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  786. package/lib/feature-libraries/flex-tree/observer.d.ts +1 -1
  787. package/lib/feature-libraries/flex-tree/observer.d.ts.map +1 -1
  788. package/lib/feature-libraries/flex-tree/observer.js.map +1 -1
  789. package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  790. package/lib/feature-libraries/forest-summary/codec.js +1 -1
  791. package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
  792. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  793. package/lib/feature-libraries/forest-summary/forestSummarizer.js +3 -3
  794. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  795. package/lib/feature-libraries/forest-summary/formatV1.d.ts.map +1 -1
  796. package/lib/feature-libraries/forest-summary/formatV1.js.map +1 -1
  797. package/lib/feature-libraries/forest-summary/formatV2.d.ts.map +1 -1
  798. package/lib/feature-libraries/forest-summary/formatV2.js.map +1 -1
  799. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +4 -4
  800. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  801. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +2 -2
  802. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  803. package/lib/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -1
  804. package/lib/feature-libraries/forest-summary/summaryTypes.js.map +1 -1
  805. package/lib/feature-libraries/index.d.ts +3 -3
  806. package/lib/feature-libraries/index.d.ts.map +1 -1
  807. package/lib/feature-libraries/index.js +2 -2
  808. package/lib/feature-libraries/index.js.map +1 -1
  809. package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
  810. package/lib/feature-libraries/mapTreeCursor.js +1 -2
  811. package/lib/feature-libraries/mapTreeCursor.js.map +1 -1
  812. package/lib/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
  813. package/lib/feature-libraries/mitigatedChangeFamily.js +2 -2
  814. package/lib/feature-libraries/mitigatedChangeFamily.js.map +1 -1
  815. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +21 -97
  816. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  817. package/lib/feature-libraries/modular-schema/crossFieldQueries.js +5 -3
  818. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  819. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +51 -20
  820. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  821. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  822. package/lib/feature-libraries/modular-schema/fieldKindConfiguration.d.ts.map +1 -1
  823. package/lib/feature-libraries/modular-schema/fieldKindConfiguration.js.map +1 -1
  824. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts +1 -1
  825. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  826. package/lib/feature-libraries/modular-schema/genericFieldKind.js +11 -5
  827. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  828. package/lib/feature-libraries/modular-schema/index.d.ts +4 -4
  829. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  830. package/lib/feature-libraries/modular-schema/index.js +2 -2
  831. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  832. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +28 -11
  833. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
  834. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +144 -246
  835. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
  836. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -1
  837. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js +1 -1
  838. package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -1
  839. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  840. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +1 -8
  841. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  842. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +21 -49
  843. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  844. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +463 -1319
  845. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  846. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
  847. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
  848. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +8 -44
  849. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  850. package/lib/feature-libraries/modular-schema/modularChangeTypes.js +1 -1
  851. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  852. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  853. package/lib/feature-libraries/object-forest/objectForest.js +2 -2
  854. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  855. package/lib/feature-libraries/optional-field/index.d.ts +2 -2
  856. package/lib/feature-libraries/optional-field/index.d.ts.map +1 -1
  857. package/lib/feature-libraries/optional-field/index.js +2 -2
  858. package/lib/feature-libraries/optional-field/index.js.map +1 -1
  859. package/lib/feature-libraries/optional-field/optionalField.d.ts +34 -5
  860. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  861. package/lib/feature-libraries/optional-field/optionalField.js +453 -221
  862. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  863. package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +33 -24
  864. package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
  865. package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
  866. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
  867. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
  868. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js +26 -55
  869. package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
  870. package/lib/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
  871. package/lib/feature-libraries/optional-field/optionalFieldCodecs.js +1 -5
  872. package/lib/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
  873. package/lib/feature-libraries/optional-field/requiredField.d.ts +36 -0
  874. package/lib/feature-libraries/optional-field/requiredField.d.ts.map +1 -0
  875. package/lib/feature-libraries/optional-field/requiredField.js +24 -0
  876. package/lib/feature-libraries/optional-field/requiredField.js.map +1 -0
  877. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.d.ts +1 -1
  878. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
  879. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js +1 -1
  880. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
  881. package/lib/feature-libraries/schema-edits/schemaChangeFormat.d.ts.map +1 -1
  882. package/lib/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
  883. package/lib/feature-libraries/schemaChecker.d.ts.map +1 -1
  884. package/lib/feature-libraries/schemaChecker.js +1 -1
  885. package/lib/feature-libraries/schemaChecker.js.map +1 -1
  886. package/lib/feature-libraries/sequence-field/compose.d.ts +7 -6
  887. package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
  888. package/lib/feature-libraries/sequence-field/compose.js +261 -85
  889. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  890. package/lib/feature-libraries/sequence-field/helperTypes.d.ts +10 -14
  891. package/lib/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
  892. package/lib/feature-libraries/sequence-field/helperTypes.js.map +1 -1
  893. package/lib/feature-libraries/sequence-field/index.d.ts +2 -13
  894. package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
  895. package/lib/feature-libraries/sequence-field/index.js +1 -12
  896. package/lib/feature-libraries/sequence-field/index.js.map +1 -1
  897. package/lib/feature-libraries/sequence-field/invert.d.ts +3 -3
  898. package/lib/feature-libraries/sequence-field/invert.d.ts.map +1 -1
  899. package/lib/feature-libraries/sequence-field/invert.js +169 -67
  900. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  901. package/lib/feature-libraries/sequence-field/markQueue.d.ts +2 -2
  902. package/lib/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
  903. package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
  904. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +56 -4
  905. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  906. package/lib/feature-libraries/sequence-field/moveEffectTable.js +84 -6
  907. package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  908. package/lib/feature-libraries/sequence-field/rebase.d.ts +3 -3
  909. package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  910. package/lib/feature-libraries/sequence-field/rebase.js +116 -109
  911. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  912. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +9 -0
  913. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +1 -0
  914. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js +46 -0
  915. package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js.map +1 -0
  916. package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
  917. package/lib/feature-libraries/sequence-field/replaceRevisions.js +31 -18
  918. package/lib/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
  919. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  920. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -0
  921. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  922. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +4 -22
  923. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
  924. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +182 -356
  925. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  926. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
  927. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js +63 -21
  928. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
  929. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
  930. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
  931. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
  932. package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
  933. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  934. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  935. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +109 -14
  936. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  937. package/lib/feature-libraries/sequence-field/sequenceKind.d.ts +16 -0
  938. package/lib/feature-libraries/sequence-field/sequenceKind.d.ts.map +1 -0
  939. package/lib/feature-libraries/sequence-field/sequenceKind.js +21 -0
  940. package/lib/feature-libraries/sequence-field/sequenceKind.js.map +1 -0
  941. package/lib/feature-libraries/sequence-field/types.d.ts +59 -30
  942. package/lib/feature-libraries/sequence-field/types.d.ts.map +1 -1
  943. package/lib/feature-libraries/sequence-field/types.js.map +1 -1
  944. package/lib/feature-libraries/sequence-field/utils.d.ts +24 -15
  945. package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  946. package/lib/feature-libraries/sequence-field/utils.js +298 -112
  947. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  948. package/lib/index.d.ts +1 -1
  949. package/lib/index.d.ts.map +1 -1
  950. package/lib/index.js +1 -1
  951. package/lib/index.js.map +1 -1
  952. package/lib/packageVersion.d.ts +1 -1
  953. package/lib/packageVersion.d.ts.map +1 -1
  954. package/lib/packageVersion.js +1 -1
  955. package/lib/packageVersion.js.map +1 -1
  956. package/lib/shared-tree/independentView.d.ts.map +1 -1
  957. package/lib/shared-tree/independentView.js +3 -3
  958. package/lib/shared-tree/independentView.js.map +1 -1
  959. package/lib/shared-tree/index.d.ts +1 -1
  960. package/lib/shared-tree/index.d.ts.map +1 -1
  961. package/lib/shared-tree/index.js.map +1 -1
  962. package/lib/shared-tree/schematizeTree.d.ts +4 -4
  963. package/lib/shared-tree/schematizeTree.d.ts.map +1 -1
  964. package/lib/shared-tree/schematizeTree.js +2 -3
  965. package/lib/shared-tree/schematizeTree.js.map +1 -1
  966. package/lib/shared-tree/schematizingTreeView.d.ts +5 -1
  967. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  968. package/lib/shared-tree/schematizingTreeView.js +42 -43
  969. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  970. package/lib/shared-tree/sharedTree.d.ts +5 -11
  971. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  972. package/lib/shared-tree/sharedTree.js +5 -43
  973. package/lib/shared-tree/sharedTree.js.map +1 -1
  974. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
  975. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  976. package/lib/shared-tree/sharedTreeChangeCodecs.js +0 -1
  977. package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  978. package/lib/shared-tree/sharedTreeChangeEnricher.d.ts +31 -24
  979. package/lib/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
  980. package/lib/shared-tree/sharedTreeChangeEnricher.js +74 -56
  981. package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  982. package/lib/shared-tree/sharedTreeChangeFamily.d.ts +5 -5
  983. package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
  984. package/lib/shared-tree/sharedTreeChangeFamily.js +5 -11
  985. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  986. package/lib/shared-tree/sharedTreeEditBuilder.d.ts +6 -16
  987. package/lib/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
  988. package/lib/shared-tree/sharedTreeEditBuilder.js +6 -12
  989. package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  990. package/lib/shared-tree/tree.d.ts.map +1 -1
  991. package/lib/shared-tree/tree.js +7 -7
  992. package/lib/shared-tree/tree.js.map +1 -1
  993. package/lib/shared-tree/treeAlpha.d.ts +1 -1
  994. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  995. package/lib/shared-tree/treeAlpha.js +3 -3
  996. package/lib/shared-tree/treeAlpha.js.map +1 -1
  997. package/lib/shared-tree/treeCheckout.d.ts +29 -13
  998. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  999. package/lib/shared-tree/treeCheckout.js +55 -54
  1000. package/lib/shared-tree/treeCheckout.js.map +1 -1
  1001. package/lib/shared-tree-core/branch.d.ts +3 -4
  1002. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  1003. package/lib/shared-tree-core/branch.js +3 -4
  1004. package/lib/shared-tree-core/branch.js.map +1 -1
  1005. package/lib/shared-tree-core/branchCommitEnricher.d.ts +18 -31
  1006. package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  1007. package/lib/shared-tree-core/branchCommitEnricher.js +24 -76
  1008. package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
  1009. package/lib/shared-tree-core/branchIdCodec.d.ts.map +1 -1
  1010. package/lib/shared-tree-core/branchIdCodec.js.map +1 -1
  1011. package/lib/shared-tree-core/changeEnricher.d.ts +8 -43
  1012. package/lib/shared-tree-core/changeEnricher.d.ts.map +1 -1
  1013. package/lib/shared-tree-core/changeEnricher.js +1 -11
  1014. package/lib/shared-tree-core/changeEnricher.js.map +1 -1
  1015. package/lib/shared-tree-core/defaultResubmitMachine.d.ts +4 -12
  1016. package/lib/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
  1017. package/lib/shared-tree-core/defaultResubmitMachine.js +28 -38
  1018. package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  1019. package/lib/shared-tree-core/editManager.d.ts +3 -3
  1020. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  1021. package/lib/shared-tree-core/editManager.js +11 -11
  1022. package/lib/shared-tree-core/editManager.js.map +1 -1
  1023. package/lib/shared-tree-core/editManagerCodecs.d.ts +1 -5
  1024. package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  1025. package/lib/shared-tree-core/editManagerCodecs.js +1 -8
  1026. package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
  1027. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +1 -1
  1028. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  1029. package/lib/shared-tree-core/editManagerCodecsCommons.js +1 -2
  1030. package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  1031. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  1032. package/lib/shared-tree-core/editManagerCodecsV1toV4.js +1 -1
  1033. package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  1034. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  1035. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js +1 -1
  1036. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  1037. package/lib/shared-tree-core/editManagerFormatCommons.d.ts +0 -1
  1038. package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
  1039. package/lib/shared-tree-core/editManagerFormatCommons.js +0 -6
  1040. package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  1041. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
  1042. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
  1043. package/lib/shared-tree-core/editManagerFormatV1toV4.js +0 -1
  1044. package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  1045. package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts +1 -1
  1046. package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -1
  1047. package/lib/shared-tree-core/editManagerFormatVSharedBranches.js +1 -1
  1048. package/lib/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
  1049. package/lib/shared-tree-core/index.d.ts +4 -4
  1050. package/lib/shared-tree-core/index.d.ts.map +1 -1
  1051. package/lib/shared-tree-core/index.js +2 -3
  1052. package/lib/shared-tree-core/index.js.map +1 -1
  1053. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts +2 -2
  1054. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  1055. package/lib/shared-tree-core/messageCodecV1ToV4.js +1 -1
  1056. package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  1057. package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts +1 -1
  1058. package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  1059. package/lib/shared-tree-core/messageCodecVSharedBranches.js +2 -2
  1060. package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  1061. package/lib/shared-tree-core/messageCodecs.d.ts +2 -6
  1062. package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
  1063. package/lib/shared-tree-core/messageCodecs.js +1 -8
  1064. package/lib/shared-tree-core/messageCodecs.js.map +1 -1
  1065. package/lib/shared-tree-core/messageFormat.d.ts +0 -1
  1066. package/lib/shared-tree-core/messageFormat.d.ts.map +1 -1
  1067. package/lib/shared-tree-core/messageFormat.js +0 -6
  1068. package/lib/shared-tree-core/messageFormat.js.map +1 -1
  1069. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +2 -2
  1070. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
  1071. package/lib/shared-tree-core/messageFormatV1ToV4.js +0 -1
  1072. package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  1073. package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -1
  1074. package/lib/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
  1075. package/lib/shared-tree-core/messageTypes.d.ts.map +1 -1
  1076. package/lib/shared-tree-core/messageTypes.js.map +1 -1
  1077. package/lib/shared-tree-core/sharedTreeCore.d.ts +8 -5
  1078. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  1079. package/lib/shared-tree-core/sharedTreeCore.js +15 -15
  1080. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  1081. package/lib/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
  1082. package/lib/shared-tree-core/versionedSummarizer.js +1 -1
  1083. package/lib/shared-tree-core/versionedSummarizer.js.map +1 -1
  1084. package/lib/simple-tree/api/configuration.d.ts +2 -2
  1085. package/lib/simple-tree/api/configuration.d.ts.map +1 -1
  1086. package/lib/simple-tree/api/configuration.js +4 -4
  1087. package/lib/simple-tree/api/configuration.js.map +1 -1
  1088. package/lib/simple-tree/api/create.d.ts +1 -1
  1089. package/lib/simple-tree/api/create.d.ts.map +1 -1
  1090. package/lib/simple-tree/api/create.js +1 -1
  1091. package/lib/simple-tree/api/create.js.map +1 -1
  1092. package/lib/simple-tree/api/dirtyIndex.d.ts +1 -1
  1093. package/lib/simple-tree/api/dirtyIndex.d.ts.map +1 -1
  1094. package/lib/simple-tree/api/dirtyIndex.js.map +1 -1
  1095. package/lib/simple-tree/api/discrepancies.d.ts.map +1 -1
  1096. package/lib/simple-tree/api/discrepancies.js +3 -3
  1097. package/lib/simple-tree/api/discrepancies.js.map +1 -1
  1098. package/lib/simple-tree/api/getJsonSchema.d.ts +1 -1
  1099. package/lib/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  1100. package/lib/simple-tree/api/getJsonSchema.js +1 -1
  1101. package/lib/simple-tree/api/getJsonSchema.js.map +1 -1
  1102. package/lib/simple-tree/api/identifierIndex.d.ts +2 -2
  1103. package/lib/simple-tree/api/identifierIndex.d.ts.map +1 -1
  1104. package/lib/simple-tree/api/identifierIndex.js.map +1 -1
  1105. package/lib/simple-tree/api/incrementalAllowedTypes.d.ts +1 -1
  1106. package/lib/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -1
  1107. package/lib/simple-tree/api/incrementalAllowedTypes.js +3 -3
  1108. package/lib/simple-tree/api/incrementalAllowedTypes.js.map +1 -1
  1109. package/lib/simple-tree/api/schemaCompatibilityTester.d.ts +1 -1
  1110. package/lib/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
  1111. package/lib/simple-tree/api/schemaCompatibilityTester.js +1 -1
  1112. package/lib/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
  1113. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +2 -2
  1114. package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  1115. package/lib/simple-tree/api/schemaCreationUtilities.js +1 -1
  1116. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  1117. package/lib/simple-tree/api/schemaFactory.d.ts +2 -2
  1118. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  1119. package/lib/simple-tree/api/schemaFactory.js +2 -2
  1120. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  1121. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +6 -6
  1122. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  1123. package/lib/simple-tree/api/schemaFactoryAlpha.js +1 -1
  1124. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  1125. package/lib/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
  1126. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  1127. package/lib/simple-tree/api/schemaFactoryBeta.js +1 -0
  1128. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  1129. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
  1130. package/lib/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
  1131. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  1132. package/lib/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
  1133. package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
  1134. package/lib/simple-tree/api/schemaStatics.d.ts.map +1 -1
  1135. package/lib/simple-tree/api/schemaStatics.js.map +1 -1
  1136. package/lib/simple-tree/api/simpleSchemaCodec.d.ts +1 -1
  1137. package/lib/simple-tree/api/simpleSchemaCodec.d.ts.map +1 -1
  1138. package/lib/simple-tree/api/simpleSchemaCodec.js +3 -3
  1139. package/lib/simple-tree/api/simpleSchemaCodec.js.map +1 -1
  1140. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +2 -2
  1141. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  1142. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +2 -2
  1143. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  1144. package/lib/simple-tree/api/simpleTreeIndex.d.ts +1 -1
  1145. package/lib/simple-tree/api/simpleTreeIndex.d.ts.map +1 -1
  1146. package/lib/simple-tree/api/simpleTreeIndex.js +1 -1
  1147. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  1148. package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
  1149. package/lib/simple-tree/api/snapshotCompatibilityChecker.js +5 -5
  1150. package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  1151. package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
  1152. package/lib/simple-tree/api/storedSchema.js.map +1 -1
  1153. package/lib/simple-tree/api/tree.d.ts +2 -2
  1154. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  1155. package/lib/simple-tree/api/tree.js.map +1 -1
  1156. package/lib/simple-tree/api/treeBeta.d.ts +1 -1
  1157. package/lib/simple-tree/api/treeBeta.d.ts.map +1 -1
  1158. package/lib/simple-tree/api/treeBeta.js +2 -2
  1159. package/lib/simple-tree/api/treeBeta.js.map +1 -1
  1160. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  1161. package/lib/simple-tree/api/treeNodeApi.js +4 -4
  1162. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  1163. package/lib/simple-tree/api/typesUnsafe.d.ts +1 -1
  1164. package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  1165. package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
  1166. package/lib/simple-tree/api/verboseTree.d.ts +1 -1
  1167. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  1168. package/lib/simple-tree/api/verboseTree.js +3 -3
  1169. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  1170. package/lib/simple-tree/core/allowedTypes.d.ts +1 -1
  1171. package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
  1172. package/lib/simple-tree/core/allowedTypes.js +2 -2
  1173. package/lib/simple-tree/core/allowedTypes.js.map +1 -1
  1174. package/lib/simple-tree/core/context.d.ts.map +1 -1
  1175. package/lib/simple-tree/core/context.js.map +1 -1
  1176. package/lib/simple-tree/core/treeNode.d.ts.map +1 -1
  1177. package/lib/simple-tree/core/treeNode.js +1 -1
  1178. package/lib/simple-tree/core/treeNode.js.map +1 -1
  1179. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  1180. package/lib/simple-tree/core/treeNodeKernel.js +1 -3
  1181. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  1182. package/lib/simple-tree/core/treeNodeSchema.d.ts +5 -5
  1183. package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  1184. package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
  1185. package/lib/simple-tree/core/treeNodeValid.d.ts +3 -3
  1186. package/lib/simple-tree/core/treeNodeValid.d.ts.map +1 -1
  1187. package/lib/simple-tree/core/treeNodeValid.js +2 -2
  1188. package/lib/simple-tree/core/treeNodeValid.js.map +1 -1
  1189. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +16 -16
  1190. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  1191. package/lib/simple-tree/core/unhydratedFlexTree.js +8 -58
  1192. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  1193. package/lib/simple-tree/core/withType.d.ts.map +1 -1
  1194. package/lib/simple-tree/core/withType.js.map +1 -1
  1195. package/lib/simple-tree/createContext.d.ts.map +1 -1
  1196. package/lib/simple-tree/createContext.js.map +1 -1
  1197. package/lib/simple-tree/fieldSchema.d.ts +5 -5
  1198. package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
  1199. package/lib/simple-tree/fieldSchema.js.map +1 -1
  1200. package/lib/simple-tree/index.d.ts +2 -2
  1201. package/lib/simple-tree/index.d.ts.map +1 -1
  1202. package/lib/simple-tree/index.js +1 -1
  1203. package/lib/simple-tree/index.js.map +1 -1
  1204. package/lib/simple-tree/leafNodeSchema.d.ts +1 -1
  1205. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  1206. package/lib/simple-tree/leafNodeSchema.js +2 -2
  1207. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  1208. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts +1 -1
  1209. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  1210. package/lib/simple-tree/node-kinds/array/arrayNode.js +6 -8
  1211. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  1212. package/lib/simple-tree/node-kinds/array/arrayNodeTypes.d.ts +1 -1
  1213. package/lib/simple-tree/node-kinds/array/arrayNodeTypes.d.ts.map +1 -1
  1214. package/lib/simple-tree/node-kinds/array/arrayNodeTypes.js.map +1 -1
  1215. package/lib/simple-tree/node-kinds/common.d.ts.map +1 -1
  1216. package/lib/simple-tree/node-kinds/common.js +2 -2
  1217. package/lib/simple-tree/node-kinds/common.js.map +1 -1
  1218. package/lib/simple-tree/node-kinds/map/mapNode.d.ts +2 -2
  1219. package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  1220. package/lib/simple-tree/node-kinds/map/mapNode.js +8 -8
  1221. package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  1222. package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts +1 -1
  1223. package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
  1224. package/lib/simple-tree/node-kinds/map/mapNodeTypes.js.map +1 -1
  1225. package/lib/simple-tree/node-kinds/object/objectNode.d.ts +2 -2
  1226. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  1227. package/lib/simple-tree/node-kinds/object/objectNode.js +22 -22
  1228. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  1229. package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts +3 -3
  1230. package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
  1231. package/lib/simple-tree/node-kinds/object/objectNodeTypes.js.map +1 -1
  1232. package/lib/simple-tree/node-kinds/record/recordNode.d.ts +1 -1
  1233. package/lib/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
  1234. package/lib/simple-tree/node-kinds/record/recordNode.js +6 -8
  1235. package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
  1236. package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts +1 -1
  1237. package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts.map +1 -1
  1238. package/lib/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
  1239. package/lib/simple-tree/prepareForInsertion.d.ts +47 -54
  1240. package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
  1241. package/lib/simple-tree/prepareForInsertion.js +125 -184
  1242. package/lib/simple-tree/prepareForInsertion.js.map +1 -1
  1243. package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
  1244. package/lib/simple-tree/simpleSchema.js.map +1 -1
  1245. package/lib/simple-tree/treeSchema.d.ts.map +1 -1
  1246. package/lib/simple-tree/treeSchema.js.map +1 -1
  1247. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +4 -13
  1248. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  1249. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +13 -30
  1250. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  1251. package/lib/tableSchema.d.ts.map +1 -1
  1252. package/lib/tableSchema.js +2 -1
  1253. package/lib/tableSchema.js.map +1 -1
  1254. package/lib/text/index.d.ts +1 -0
  1255. package/lib/text/index.d.ts.map +1 -1
  1256. package/lib/text/index.js +1 -0
  1257. package/lib/text/index.js.map +1 -1
  1258. package/lib/text/textDomain.d.ts +8 -0
  1259. package/lib/text/textDomain.d.ts.map +1 -1
  1260. package/lib/text/textDomain.js +1 -1
  1261. package/lib/text/textDomain.js.map +1 -1
  1262. package/lib/text/textDomainFormatted.d.ts +572 -0
  1263. package/lib/text/textDomainFormatted.d.ts.map +1 -0
  1264. package/lib/text/textDomainFormatted.js +180 -0
  1265. package/lib/text/textDomainFormatted.js.map +1 -0
  1266. package/lib/treeFactory.d.ts.map +1 -1
  1267. package/lib/treeFactory.js +4 -14
  1268. package/lib/treeFactory.js.map +1 -1
  1269. package/lib/util/bTreeUtils.d.ts.map +1 -1
  1270. package/lib/util/bTreeUtils.js +1 -1
  1271. package/lib/util/bTreeUtils.js.map +1 -1
  1272. package/lib/util/index.d.ts +1 -1
  1273. package/lib/util/index.d.ts.map +1 -1
  1274. package/lib/util/index.js +1 -1
  1275. package/lib/util/index.js.map +1 -1
  1276. package/lib/util/rangeMap.d.ts +12 -24
  1277. package/lib/util/rangeMap.d.ts.map +1 -1
  1278. package/lib/util/rangeMap.js +5 -44
  1279. package/lib/util/rangeMap.js.map +1 -1
  1280. package/lib/util/readSnapshotBlob.d.ts +1 -1
  1281. package/lib/util/readSnapshotBlob.d.ts.map +1 -1
  1282. package/lib/util/readSnapshotBlob.js.map +1 -1
  1283. package/package.json +22 -22
  1284. package/src/codec/codec.ts +10 -7
  1285. package/src/codec/versioned/codec.ts +3 -3
  1286. package/src/core/change-family/changeFamily.ts +0 -5
  1287. package/src/core/change-family/index.ts +0 -1
  1288. package/src/core/index.ts +1 -4
  1289. package/src/core/rebase/changeRebaser.ts +1 -6
  1290. package/src/core/rebase/index.ts +0 -1
  1291. package/src/core/rebase/types.ts +1 -8
  1292. package/src/core/rebase/utils.ts +7 -31
  1293. package/src/core/schema-stored/formatV2.ts +2 -1
  1294. package/src/core/tree/anchorSet.ts +1 -1
  1295. package/src/core/tree/detachedFieldIndex.ts +2 -18
  1296. package/src/core/tree/detachedFieldIndexCodecCommon.ts +2 -1
  1297. package/src/core/tree/detachedFieldIndexCodecV1.ts +2 -2
  1298. package/src/core/tree/detachedFieldIndexCodecV2.ts +3 -3
  1299. package/src/core/tree/detachedFieldIndexFormatV1.ts +3 -2
  1300. package/src/core/tree/detachedFieldIndexFormatV2.ts +3 -2
  1301. package/src/core/tree/index.ts +1 -2
  1302. package/src/core/tree/pathTree.ts +4 -16
  1303. package/src/core/tree/visitDelta.ts +2 -3
  1304. package/src/core/tree/visitorUtils.ts +2 -1
  1305. package/src/feature-libraries/changeAtomIdBTree.ts +4 -28
  1306. package/src/feature-libraries/chunked-forest/basicChunk.ts +1 -7
  1307. package/src/feature-libraries/chunked-forest/chunkTree.ts +2 -7
  1308. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +1 -1
  1309. package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +1 -1
  1310. package/src/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.ts +1 -1
  1311. package/src/feature-libraries/chunked-forest/codec/codecs.ts +2 -2
  1312. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +1 -1
  1313. package/src/feature-libraries/chunked-forest/codec/format.ts +1 -1
  1314. package/src/feature-libraries/chunked-forest/codec/formatGeneric.ts +1 -0
  1315. package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +3 -3
  1316. package/src/feature-libraries/default-schema/defaultEditBuilder.ts +128 -405
  1317. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +27 -123
  1318. package/src/feature-libraries/default-schema/index.ts +5 -22
  1319. package/src/feature-libraries/default-schema/mappedEditBuilder.ts +9 -35
  1320. package/src/feature-libraries/deltaUtils.ts +1 -6
  1321. package/src/feature-libraries/fieldKindIdentifiers.ts +16 -0
  1322. package/src/feature-libraries/flex-tree/context.ts +0 -17
  1323. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +8 -7
  1324. package/src/feature-libraries/flex-tree/lazyField.ts +26 -69
  1325. package/src/feature-libraries/flex-tree/observer.ts +3 -1
  1326. package/src/feature-libraries/forest-summary/codec.ts +1 -1
  1327. package/src/feature-libraries/forest-summary/forestSummarizer.ts +6 -6
  1328. package/src/feature-libraries/forest-summary/formatV1.ts +1 -0
  1329. package/src/feature-libraries/forest-summary/formatV2.ts +1 -0
  1330. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +9 -7
  1331. package/src/feature-libraries/forest-summary/summaryTypes.ts +1 -0
  1332. package/src/feature-libraries/index.ts +8 -27
  1333. package/src/feature-libraries/mapTreeCursor.ts +2 -3
  1334. package/src/feature-libraries/mitigatedChangeFamily.ts +1 -3
  1335. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +44 -142
  1336. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +58 -32
  1337. package/src/feature-libraries/modular-schema/fieldKindConfiguration.ts +1 -0
  1338. package/src/feature-libraries/modular-schema/genericFieldKind.ts +20 -8
  1339. package/src/feature-libraries/modular-schema/index.ts +15 -16
  1340. package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +336 -543
  1341. package/src/feature-libraries/modular-schema/modularChangeCodecV2.ts +2 -2
  1342. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +3 -15
  1343. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +753 -2582
  1344. package/src/feature-libraries/modular-schema/modularChangeFormatV1.ts +0 -1
  1345. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +8 -55
  1346. package/src/feature-libraries/object-forest/objectForest.ts +2 -2
  1347. package/src/feature-libraries/optional-field/index.ts +5 -5
  1348. package/src/feature-libraries/optional-field/optionalField.ts +592 -317
  1349. package/src/feature-libraries/optional-field/optionalFieldChangeTypes.ts +38 -24
  1350. package/src/feature-libraries/optional-field/optionalFieldCodecV2.ts +35 -89
  1351. package/src/feature-libraries/optional-field/optionalFieldCodecs.ts +1 -5
  1352. package/src/feature-libraries/optional-field/requiredField.ts +62 -0
  1353. package/src/feature-libraries/schema-edits/schemaChangeCodecs.ts +1 -1
  1354. package/src/feature-libraries/schema-edits/schemaChangeFormat.ts +1 -0
  1355. package/src/feature-libraries/schemaChecker.ts +3 -2
  1356. package/src/feature-libraries/sequence-field/compose.ts +522 -139
  1357. package/src/feature-libraries/sequence-field/helperTypes.ts +19 -34
  1358. package/src/feature-libraries/sequence-field/index.ts +2 -42
  1359. package/src/feature-libraries/sequence-field/invert.ts +228 -103
  1360. package/src/feature-libraries/sequence-field/markQueue.ts +2 -2
  1361. package/src/feature-libraries/sequence-field/moveEffectTable.ts +195 -8
  1362. package/src/feature-libraries/sequence-field/rebase.ts +205 -169
  1363. package/src/feature-libraries/sequence-field/relevantRemovedRoots.ts +57 -0
  1364. package/src/feature-libraries/sequence-field/replaceRevisions.ts +47 -25
  1365. package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +2 -0
  1366. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +228 -648
  1367. package/src/feature-libraries/sequence-field/sequenceFieldCodecV3.ts +70 -56
  1368. package/src/feature-libraries/sequence-field/sequenceFieldEditor.ts +27 -25
  1369. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +129 -19
  1370. package/src/feature-libraries/sequence-field/sequenceKind.ts +40 -0
  1371. package/src/feature-libraries/sequence-field/types.ts +64 -34
  1372. package/src/feature-libraries/sequence-field/utils.ts +353 -139
  1373. package/src/index.ts +1 -1
  1374. package/src/packageVersion.ts +1 -1
  1375. package/src/shared-tree/independentView.ts +4 -3
  1376. package/src/shared-tree/index.ts +2 -3
  1377. package/src/shared-tree/schematizeTree.ts +8 -21
  1378. package/src/shared-tree/schematizingTreeView.ts +79 -61
  1379. package/src/shared-tree/sharedTree.ts +10 -64
  1380. package/src/shared-tree/sharedTreeChangeCodecs.ts +2 -5
  1381. package/src/shared-tree/sharedTreeChangeEnricher.ts +87 -68
  1382. package/src/shared-tree/sharedTreeChangeFamily.ts +5 -15
  1383. package/src/shared-tree/sharedTreeEditBuilder.ts +8 -39
  1384. package/src/shared-tree/tree.ts +10 -10
  1385. package/src/shared-tree/treeAlpha.ts +26 -25
  1386. package/src/shared-tree/treeCheckout.ts +119 -94
  1387. package/src/shared-tree-core/branch.ts +6 -12
  1388. package/src/shared-tree-core/branchCommitEnricher.ts +25 -77
  1389. package/src/shared-tree-core/branchIdCodec.ts +1 -0
  1390. package/src/shared-tree-core/changeEnricher.ts +8 -52
  1391. package/src/shared-tree-core/defaultResubmitMachine.ts +39 -51
  1392. package/src/shared-tree-core/editManager.ts +8 -22
  1393. package/src/shared-tree-core/editManagerCodecs.ts +3 -13
  1394. package/src/shared-tree-core/editManagerCodecsCommons.ts +7 -6
  1395. package/src/shared-tree-core/editManagerCodecsV1toV4.ts +1 -1
  1396. package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +2 -2
  1397. package/src/shared-tree-core/editManagerFormatCommons.ts +1 -6
  1398. package/src/shared-tree-core/editManagerFormatV1toV4.ts +2 -3
  1399. package/src/shared-tree-core/editManagerFormatVSharedBranches.ts +3 -2
  1400. package/src/shared-tree-core/index.ts +2 -7
  1401. package/src/shared-tree-core/messageCodecV1ToV4.ts +4 -5
  1402. package/src/shared-tree-core/messageCodecVSharedBranches.ts +4 -4
  1403. package/src/shared-tree-core/messageCodecs.ts +3 -13
  1404. package/src/shared-tree-core/messageFormat.ts +0 -6
  1405. package/src/shared-tree-core/messageFormatV1ToV4.ts +2 -3
  1406. package/src/shared-tree-core/messageFormatVSharedBranches.ts +1 -0
  1407. package/src/shared-tree-core/messageTypes.ts +1 -0
  1408. package/src/shared-tree-core/sharedTreeCore.ts +27 -31
  1409. package/src/shared-tree-core/versionedSummarizer.ts +3 -1
  1410. package/src/simple-tree/api/configuration.ts +9 -9
  1411. package/src/simple-tree/api/create.ts +7 -6
  1412. package/src/simple-tree/api/dirtyIndex.ts +4 -2
  1413. package/src/simple-tree/api/discrepancies.ts +9 -8
  1414. package/src/simple-tree/api/getJsonSchema.ts +4 -3
  1415. package/src/simple-tree/api/identifierIndex.ts +4 -2
  1416. package/src/simple-tree/api/incrementalAllowedTypes.ts +6 -5
  1417. package/src/simple-tree/api/schemaCompatibilityTester.ts +3 -3
  1418. package/src/simple-tree/api/schemaCreationUtilities.ts +4 -3
  1419. package/src/simple-tree/api/schemaFactory.ts +16 -17
  1420. package/src/simple-tree/api/schemaFactoryAlpha.ts +21 -21
  1421. package/src/simple-tree/api/schemaFactoryBeta.ts +17 -15
  1422. package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
  1423. package/src/simple-tree/api/schemaFromSimple.ts +1 -1
  1424. package/src/simple-tree/api/schemaStatics.ts +2 -0
  1425. package/src/simple-tree/api/simpleSchemaCodec.ts +12 -11
  1426. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +20 -18
  1427. package/src/simple-tree/api/simpleTreeIndex.ts +6 -4
  1428. package/src/simple-tree/api/snapshotCompatibilityChecker.ts +7 -5
  1429. package/src/simple-tree/api/storedSchema.ts +2 -1
  1430. package/src/simple-tree/api/tree.ts +2 -2
  1431. package/src/simple-tree/api/treeBeta.ts +3 -3
  1432. package/src/simple-tree/api/treeNodeApi.ts +14 -13
  1433. package/src/simple-tree/api/typesUnsafe.ts +7 -8
  1434. package/src/simple-tree/api/verboseTree.ts +6 -5
  1435. package/src/simple-tree/core/allowedTypes.ts +4 -4
  1436. package/src/simple-tree/core/context.ts +1 -1
  1437. package/src/simple-tree/core/treeNode.ts +1 -1
  1438. package/src/simple-tree/core/treeNodeKernel.ts +1 -3
  1439. package/src/simple-tree/core/treeNodeSchema.ts +7 -6
  1440. package/src/simple-tree/core/treeNodeValid.ts +9 -9
  1441. package/src/simple-tree/core/unhydratedFlexTree.ts +37 -88
  1442. package/src/simple-tree/core/withType.ts +3 -2
  1443. package/src/simple-tree/createContext.ts +1 -0
  1444. package/src/simple-tree/fieldSchema.ts +5 -8
  1445. package/src/simple-tree/index.ts +1 -2
  1446. package/src/simple-tree/leafNodeSchema.ts +3 -3
  1447. package/src/simple-tree/node-kinds/array/arrayNode.ts +20 -21
  1448. package/src/simple-tree/node-kinds/array/arrayNodeTypes.ts +2 -2
  1449. package/src/simple-tree/node-kinds/common.ts +6 -3
  1450. package/src/simple-tree/node-kinds/map/mapNode.ts +20 -19
  1451. package/src/simple-tree/node-kinds/map/mapNodeTypes.ts +2 -2
  1452. package/src/simple-tree/node-kinds/object/objectNode.ts +37 -37
  1453. package/src/simple-tree/node-kinds/object/objectNodeTypes.ts +8 -7
  1454. package/src/simple-tree/node-kinds/record/recordNode.ts +21 -22
  1455. package/src/simple-tree/node-kinds/record/recordNodeTypes.ts +1 -2
  1456. package/src/simple-tree/prepareForInsertion.ts +205 -345
  1457. package/src/simple-tree/simpleSchema.ts +1 -0
  1458. package/src/simple-tree/treeSchema.ts +1 -0
  1459. package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +16 -44
  1460. package/src/tableSchema.ts +3 -1
  1461. package/src/text/index.ts +1 -0
  1462. package/src/text/textDomain.ts +1 -1
  1463. package/src/text/textDomainFormatted.ts +309 -0
  1464. package/src/treeFactory.ts +8 -18
  1465. package/src/util/bTreeUtils.ts +1 -1
  1466. package/src/util/index.ts +0 -3
  1467. package/src/util/rangeMap.ts +18 -72
  1468. package/src/util/readSnapshotBlob.ts +4 -2
  1469. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +0 -38
  1470. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +0 -1
  1471. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js +0 -132
  1472. package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js.map +0 -1
  1473. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.d.ts +0 -15
  1474. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.d.ts.map +0 -1
  1475. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.js +0 -393
  1476. package/dist/feature-libraries/modular-schema/modularChangeCodecV3.js.map +0 -1
  1477. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.d.ts +0 -146
  1478. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.d.ts.map +0 -1
  1479. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.js +0 -32
  1480. package/dist/feature-libraries/modular-schema/modularChangeFormatV3.js.map +0 -1
  1481. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +0 -23
  1482. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +0 -1
  1483. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +0 -31
  1484. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +0 -1
  1485. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +0 -12
  1486. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +0 -1
  1487. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js +0 -57
  1488. package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js.map +0 -1
  1489. package/dist/shared-tree-core/transactionEnricher.d.ts +0 -23
  1490. package/dist/shared-tree-core/transactionEnricher.d.ts.map +0 -1
  1491. package/dist/shared-tree-core/transactionEnricher.js +0 -74
  1492. package/dist/shared-tree-core/transactionEnricher.js.map +0 -1
  1493. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +0 -38
  1494. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +0 -1
  1495. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js +0 -128
  1496. package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js.map +0 -1
  1497. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.d.ts +0 -15
  1498. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.d.ts.map +0 -1
  1499. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.js +0 -389
  1500. package/lib/feature-libraries/modular-schema/modularChangeCodecV3.js.map +0 -1
  1501. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.d.ts +0 -146
  1502. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.d.ts.map +0 -1
  1503. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.js +0 -29
  1504. package/lib/feature-libraries/modular-schema/modularChangeFormatV3.js.map +0 -1
  1505. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +0 -23
  1506. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +0 -1
  1507. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +0 -27
  1508. package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +0 -1
  1509. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +0 -12
  1510. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +0 -1
  1511. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js +0 -53
  1512. package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js.map +0 -1
  1513. package/lib/shared-tree-core/transactionEnricher.d.ts +0 -23
  1514. package/lib/shared-tree-core/transactionEnricher.d.ts.map +0 -1
  1515. package/lib/shared-tree-core/transactionEnricher.js +0 -70
  1516. package/lib/shared-tree-core/transactionEnricher.js.map +0 -1
  1517. package/src/feature-libraries/default-schema/locationBasedEditBuilder.ts +0 -188
  1518. package/src/feature-libraries/modular-schema/modularChangeCodecV3.ts +0 -760
  1519. package/src/feature-libraries/modular-schema/modularChangeFormatV3.ts +0 -62
  1520. package/src/feature-libraries/optional-field/optionalFieldChangeFormatV3.ts +0 -45
  1521. package/src/feature-libraries/optional-field/optionalFieldCodecV3.ts +0 -94
  1522. package/src/shared-tree-core/transactionEnricher.ts +0 -74
@@ -4,8 +4,9 @@
4
4
  */
5
5
 
6
6
  import { assert, fail } from "@fluidframework/core-utils/internal";
7
- import { BTree } from "@tylerbu/sorted-btree-es6";
8
7
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
8
+ import { BTree } from "@tylerbu/sorted-btree-es6";
9
+ import { lt } from "semver-ts";
9
10
 
10
11
  import {
11
12
  FluidClientVersion,
@@ -27,10 +28,12 @@ import {
27
28
  EditBuilder,
28
29
  type FieldKey,
29
30
  type FieldKindIdentifier,
31
+ type FieldUpPath,
30
32
  type RevisionInfo,
31
33
  type RevisionMetadataSource,
32
34
  type RevisionTag,
33
35
  type TaggedChange,
36
+ type UpPath,
34
37
  makeDetachedNodeId,
35
38
  revisionMetadataSourceFromInfo,
36
39
  areEqualChangeAtomIds,
@@ -38,18 +41,10 @@ import {
38
41
  areEqualChangeAtomIdOpts,
39
42
  tagChange,
40
43
  makeAnonChange,
44
+ newChangeAtomIdRangeMap,
41
45
  type DeltaDetachedNodeChanges,
42
46
  type DeltaDetachedNodeRename,
43
47
  mapTaggedChange,
44
- newChangeAtomIdRangeMap,
45
- newChangeAtomIdTransform,
46
- type ChangeAtomIdRangeMap,
47
- offsetChangeAtomId,
48
- type NormalizedUpPath,
49
- type NormalizedFieldUpPath,
50
- isDetachedUpPathRoot,
51
- subtractChangeAtomIds,
52
- makeChangeAtomId,
53
48
  type RevisionReplacer,
54
49
  } from "../../core/index.js";
55
50
  import {
@@ -66,19 +61,19 @@ import {
66
61
  type TupleBTree,
67
62
  RangeMap,
68
63
  balancedReduce,
69
- type RangeQueryEntry,
70
- type RangeQueryResultFragment,
71
64
  } from "../../util/index.js";
65
+ import {
66
+ getFromChangeAtomIdMap,
67
+ setInChangeAtomIdMap,
68
+ type ChangeAtomIdBTree,
69
+ } from "../changeAtomIdBTree.js";
72
70
  import type { TreeChunk } from "../chunked-forest/index.js";
73
71
 
74
72
  import {
75
- type ComposeNodeManager,
73
+ type CrossFieldManager,
76
74
  type CrossFieldMap,
77
75
  CrossFieldTarget,
78
- type DetachedNodeEntry,
79
- type InvertNodeManager,
80
- type RebaseDetachedNodeEntry,
81
- type RebaseNodeManager,
76
+ getFirstFromCrossFieldMap,
82
77
  setInCrossFieldMap,
83
78
  } from "./crossFieldQueries.js";
84
79
  import {
@@ -86,34 +81,23 @@ import {
86
81
  NodeAttachState,
87
82
  type RebaseRevisionMetadata,
88
83
  } from "./fieldChangeHandler.js";
84
+ import type { FlexFieldKind } from "./fieldKind.js";
89
85
  import { convertGenericChange, genericFieldKind } from "./genericFieldKind.js";
90
86
  import type { GenericChangeset } from "./genericFieldKindTypes.js";
91
87
  import {
92
88
  type CrossFieldKey,
93
89
  type CrossFieldKeyRange,
94
90
  type CrossFieldKeyTable,
95
- type CrossFieldRangeTable,
96
91
  type FieldChange,
97
92
  type FieldChangeMap,
98
93
  type FieldChangeset,
99
94
  type FieldId,
100
95
  type ModularChangeset,
101
- newCrossFieldRangeTable,
96
+ newCrossFieldKeyTable,
102
97
  type NoChangeConstraint,
103
98
  type NodeChangeset,
104
99
  type NodeId,
105
- type NodeLocation,
106
- type RebaseVersion,
107
- type RootNodeTable,
108
100
  } from "./modularChangeTypes.js";
109
- import type { FlexFieldKind } from "./fieldKind.js";
110
- import { lt } from "semver-ts";
111
- import {
112
- getFromChangeAtomIdMap,
113
- rangeQueryChangeAtomIdMap,
114
- setInChangeAtomIdMap,
115
- type ChangeAtomIdBTree,
116
- } from "../changeAtomIdBTree.js";
117
101
 
118
102
  /**
119
103
  * Implementation of ChangeFamily which delegates work in a given field to the appropriate FieldKind
@@ -199,14 +183,14 @@ export class ModularChangeFamily
199
183
  }
200
184
 
201
185
  public compose(changes: TaggedChange<ModularChangeset>[]): ModularChangeset {
202
- const { maxId } = getRevInfoFromTaggedChanges(changes);
186
+ const { revInfos, maxId } = getRevInfoFromTaggedChanges(changes);
203
187
  const idState: IdAllocationState = { maxId };
204
188
 
205
189
  const pairwiseDelegate = (
206
190
  left: ModularChangeset,
207
191
  right: ModularChangeset,
208
192
  ): ModularChangeset => {
209
- return this.composePair(left, right, idState);
193
+ return this.composePair(left, right, revInfos, idState);
210
194
  };
211
195
 
212
196
  const innerChanges = changes.map((change) => change.change);
@@ -216,11 +200,10 @@ export class ModularChangeFamily
216
200
  private composePair(
217
201
  change1: ModularChangeset,
218
202
  change2: ModularChangeset,
203
+ revInfos: RevisionInfo[],
219
204
  idState: IdAllocationState,
220
205
  ): ModularChangeset {
221
- const revInfos = composeRevInfos(change1.revisions, change2.revisions);
222
-
223
- const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys, rootNodes } =
206
+ const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys } =
224
207
  this.composeAllFields(change1, change2, revInfos, idState);
225
208
 
226
209
  const { allBuilds, allDestroys, allRefreshers } = composeBuildsDestroysAndRefreshers(
@@ -233,7 +216,7 @@ export class ModularChangeFamily
233
216
  const noChangeConstraintOnRevert =
234
217
  change1.noChangeConstraintOnRevert ?? change2.noChangeConstraintOnRevert;
235
218
 
236
- const composed = makeModularChangeset({
219
+ return makeModularChangeset({
237
220
  fieldChanges,
238
221
  nodeChanges,
239
222
  nodeToParent,
@@ -241,23 +224,18 @@ export class ModularChangeFamily
241
224
  crossFieldKeys,
242
225
  maxId: idState.maxId,
243
226
  revisions: revInfos,
244
- rootNodes,
227
+ noChangeConstraint,
228
+ noChangeConstraintOnRevert,
245
229
  builds: allBuilds,
246
230
  destroys: allDestroys,
247
231
  refreshers: allRefreshers,
248
- noChangeConstraint,
249
- noChangeConstraintOnRevert,
250
232
  });
251
-
252
- // XXX: This is an expensive assert which should be disabled before merging.
253
- validateChangeset(composed, this.fieldKinds);
254
- return composed;
255
233
  }
256
234
 
257
235
  private composeAllFields(
258
236
  potentiallyConflictedChange1: ModularChangeset,
259
237
  potentiallyConflictedChange2: ModularChangeset,
260
- revInfos: readonly RevisionInfo[],
238
+ revInfos: RevisionInfo[],
261
239
  idState: IdAllocationState,
262
240
  ): ModularChangesetContent {
263
241
  // Our current cell ordering scheme in sequences depends on being able to rebase over a change with conflicts.
@@ -281,38 +259,14 @@ export class ModularChangeFamily
281
259
  mergeTupleBTrees(change1.nodeChanges, change2.nodeChanges),
282
260
  );
283
261
 
284
- const composedNodeToParent: ChangeAtomIdBTree<NodeLocation> = brand(
262
+ const composedNodeToParent: ChangeAtomIdBTree<FieldId> = brand(
285
263
  mergeTupleBTrees(change1.nodeToParent, change2.nodeToParent),
286
264
  );
287
265
  const composedNodeAliases: ChangeAtomIdBTree<NodeId> = brand(
288
266
  mergeTupleBTrees(change1.nodeAliases, change2.nodeAliases),
289
267
  );
290
268
 
291
- const pendingCompositions: PendingCompositions = {
292
- nodeIdsToCompose: [],
293
- affectedBaseFields: newTupleBTree(),
294
- };
295
-
296
- const movedCrossFieldKeys: CrossFieldKeyTable = newCrossFieldRangeTable();
297
- const removedCrossFieldKeys: CrossFieldRangeTable<boolean> = newCrossFieldRangeTable();
298
-
299
- const composedRoots = composeRootTables(
300
- change1,
301
- change2,
302
- composedNodeToParent,
303
- movedCrossFieldKeys,
304
- removedCrossFieldKeys,
305
- pendingCompositions,
306
- );
307
-
308
- const crossFieldTable = newComposeTable(
309
- change1,
310
- change2,
311
- composedRoots,
312
- movedCrossFieldKeys,
313
- removedCrossFieldKeys,
314
- pendingCompositions,
315
- );
269
+ const crossFieldTable = newComposeTable(change1, change2, composedNodeToParent);
316
270
 
317
271
  const composedFields = this.composeFieldMaps(
318
272
  change1.fieldChanges,
@@ -333,32 +287,17 @@ export class ModularChangeFamily
333
287
  revisionMetadata,
334
288
  );
335
289
 
336
- for (const entry of crossFieldTable.renamesToDelete.entries()) {
337
- deleteNodeRenameFrom(crossFieldTable.composedRootNodes, entry.start, entry.length);
338
- }
339
-
340
- for (const [nodeId, location] of crossFieldTable.movedNodeToParent.entries()) {
341
- // Moved nodes are from change2.
342
- // If there is a corresponding node in change1, then composedNodeToParent will already have the correct entry,
343
- // because the location of the node is the same in change1 and the composed change
344
- // (since they have the same input context).
345
- if (crossFieldTable.newToBaseNodeId.get(nodeId) === undefined) {
346
- composedNodeToParent.set(nodeId, location);
347
- }
348
- }
349
-
290
+ // Currently no field kinds require making changes to cross-field keys during composition, so we can just merge the two tables.
291
+ const composedCrossFieldKeys = RangeMap.union(
292
+ change1.crossFieldKeys,
293
+ change2.crossFieldKeys,
294
+ );
350
295
  return {
351
296
  fieldChanges: composedFields,
352
297
  nodeChanges: composedNodeChanges,
353
298
  nodeToParent: composedNodeToParent,
354
299
  nodeAliases: composedNodeAliases,
355
- crossFieldKeys: composeCrossFieldKeyTables(
356
- change1.crossFieldKeys,
357
- change2.crossFieldKeys,
358
- crossFieldTable.movedCrossFieldKeys,
359
- crossFieldTable.removedCrossFieldKeys,
360
- ),
361
- rootNodes: composedRoots,
300
+ crossFieldKeys: composedCrossFieldKeys,
362
301
  };
363
302
  }
364
303
 
@@ -370,16 +309,17 @@ export class ModularChangeFamily
370
309
  ): void {
371
310
  const context = crossFieldTable.fieldToContext.get(fieldChange);
372
311
  assert(context !== undefined, 0x8cc /* Should have context for every invalidated field */);
373
- const { change1: fieldChange1, change2: fieldChange2, composedChange } = context;
374
-
375
- crossFieldTable.pendingCompositions.affectedBaseFields.delete(
376
- fieldIdKeyFromFieldId(context.fieldId),
377
- );
312
+ const { fieldId, change1: fieldChange1, change2: fieldChange2, composedChange } = context;
378
313
 
379
314
  const rebaser = getChangeHandler(this.fieldKinds, composedChange.fieldKind).rebaser;
380
315
  const composeNodes = (child1: NodeId | undefined, child2: NodeId | undefined): NodeId => {
381
- if (child1 !== undefined && child2 !== undefined) {
382
- addNodesToCompose(crossFieldTable, child1, child2);
316
+ if (
317
+ child1 !== undefined &&
318
+ child2 !== undefined &&
319
+ getFromChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2) === undefined
320
+ ) {
321
+ setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
322
+ crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
383
323
  }
384
324
 
385
325
  return child1 ?? child2 ?? fail(0xb22 /* Should not compose two undefined nodes */);
@@ -390,7 +330,7 @@ export class ModularChangeFamily
390
330
  fieldChange2,
391
331
  composeNodes,
392
332
  genId,
393
- new ComposeNodeManagerI(crossFieldTable, context.fieldId, false),
333
+ new ComposeManager(crossFieldTable, fieldChange, fieldId, false),
394
334
  revisionMetadata,
395
335
  );
396
336
  composedChange.change = brand(amendedChange);
@@ -402,7 +342,7 @@ export class ModularChangeFamily
402
342
  * - discovering that two node changesets refer to the same node (`nodeIdsToCompose`)
403
343
  * - a previously composed field being invalidated by a cross field effect (`invalidatedFields`)
404
344
  * - a field which was copied directly from an input changeset being invalidated by a cross field effect
405
- * (`affectedBaseFields`)
345
+ * (`affectedBaseFields` and `affectedNewFields`)
406
346
  *
407
347
  * Updating an element may invalidate further elements. This function runs until there is no more invalidation.
408
348
  */
@@ -410,59 +350,72 @@ export class ModularChangeFamily
410
350
  table: ComposeTable,
411
351
  composedFields: FieldChangeMap,
412
352
  composedNodes: ChangeAtomIdBTree<NodeChangeset>,
413
- composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
353
+ composedNodeToParent: ChangeAtomIdBTree<FieldId>,
414
354
  nodeAliases: ChangeAtomIdBTree<NodeId>,
415
355
  genId: IdAllocator,
416
356
  metadata: RevisionMetadataSource,
417
357
  ): void {
418
358
  const pending = table.pendingCompositions;
419
- while (pending.nodeIdsToCompose.length > 0 || pending.affectedBaseFields.length > 0) {
420
- this.processPendingNodeCompositions(
359
+ while (
360
+ table.invalidatedFields.size > 0 ||
361
+ pending.nodeIdsToCompose.length > 0 ||
362
+ pending.affectedBaseFields.length > 0 ||
363
+ pending.affectedNewFields.length > 0
364
+ ) {
365
+ // Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
366
+ for (const [id1, id2] of pending.nodeIdsToCompose) {
367
+ this.composeNodesById(
368
+ table.baseChange.nodeChanges,
369
+ table.newChange.nodeChanges,
370
+ composedNodes,
371
+ composedNodeToParent,
372
+ nodeAliases,
373
+ id1,
374
+ id2,
375
+ genId,
376
+ table,
377
+ metadata,
378
+ );
379
+ }
380
+
381
+ pending.nodeIdsToCompose.length = 0;
382
+
383
+ this.composeAffectedFields(
421
384
  table,
385
+ table.baseChange,
386
+ true,
387
+ pending.affectedBaseFields,
388
+ composedFields,
422
389
  composedNodes,
423
- composedNodeToParent,
424
- nodeAliases,
425
390
  genId,
426
391
  metadata,
427
392
  );
428
393
 
429
394
  this.composeAffectedFields(
430
395
  table,
431
- table.baseChange,
432
- pending.affectedBaseFields,
396
+ table.newChange,
397
+ false,
398
+ pending.affectedNewFields,
433
399
  composedFields,
434
400
  composedNodes,
435
401
  genId,
436
402
  metadata,
437
403
  );
404
+
405
+ this.processInvalidatedCompositions(table, genId, metadata);
438
406
  }
439
407
  }
440
408
 
441
- private processPendingNodeCompositions(
409
+ private processInvalidatedCompositions(
442
410
  table: ComposeTable,
443
- composedNodes: ChangeAtomIdBTree<NodeChangeset>,
444
- composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
445
- nodeAliases: ChangeAtomIdBTree<NodeId>,
446
411
  genId: IdAllocator,
447
412
  metadata: RevisionMetadataSource,
448
413
  ): void {
449
- // Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
450
- for (const [id1, id2] of table.pendingCompositions.nodeIdsToCompose) {
451
- this.composeNodesById(
452
- table.baseChange,
453
- table.newChange,
454
- composedNodes,
455
- composedNodeToParent,
456
- nodeAliases,
457
- id1,
458
- id2,
459
- genId,
460
- table,
461
- metadata,
462
- );
414
+ const fieldsToUpdate = table.invalidatedFields;
415
+ table.invalidatedFields = new Set();
416
+ for (const fieldChange of fieldsToUpdate) {
417
+ this.composeInvalidatedField(fieldChange, table, genId, metadata);
463
418
  }
464
-
465
- table.pendingCompositions.nodeIdsToCompose.length = 0;
466
419
  }
467
420
 
468
421
  /**
@@ -479,79 +432,64 @@ export class ModularChangeFamily
479
432
  private composeAffectedFields(
480
433
  table: ComposeTable,
481
434
  change: ModularChangeset,
435
+ areBaseFields: boolean,
482
436
  affectedFields: BTree<FieldIdKey, true>,
483
437
  composedFields: FieldChangeMap,
484
438
  composedNodes: ChangeAtomIdBTree<NodeChangeset>,
485
439
  genId: IdAllocator,
486
440
  metadata: RevisionMetadataSource,
487
441
  ): void {
488
- const fieldsToProcess = affectedFields.clone();
489
- affectedFields.clear();
490
-
491
- for (const fieldIdKey of fieldsToProcess.keys()) {
492
- const fieldId = fieldIdFromFieldIdKey(fieldIdKey);
493
- const fieldChange = fieldChangeFromId(change, fieldId);
442
+ for (const fieldIdKey of affectedFields.keys()) {
443
+ const fieldId = normalizeFieldId(fieldIdFromFieldIdKey(fieldIdKey), change.nodeAliases);
444
+ const fieldChange = fieldChangeFromId(change.fieldChanges, change.nodeChanges, fieldId);
494
445
 
495
446
  if (
496
447
  table.fieldToContext.has(fieldChange) ||
497
448
  table.newFieldToBaseField.has(fieldChange)
498
449
  ) {
499
- this.composeInvalidatedField(fieldChange, table, genId, metadata);
500
- } else {
501
- this.composeFieldWithNoNewChange(
502
- table,
503
- fieldChange,
504
- fieldId,
505
- composedFields,
506
- composedNodes,
507
- genId,
508
- metadata,
509
- );
450
+ // This function handles fields which were not part of the intersection of the two changesets but which need to be updated anyway.
451
+ // If we've already processed this field then either it is up to date
452
+ // or there is pending inval which will be handled in processInvalidatedCompositions.
453
+ continue;
510
454
  }
511
- }
512
- }
513
455
 
514
- private composeFieldWithNoNewChange(
515
- table: ComposeTable,
516
- baseFieldChange: FieldChange,
517
- fieldId: FieldId,
518
- composedFields: FieldChangeMap,
519
- composedNodes: ChangeAtomIdBTree<NodeChangeset>,
520
- genId: IdAllocator,
521
- metadata: RevisionMetadataSource,
522
- ): void {
523
- const emptyChange = this.createEmptyFieldChange(baseFieldChange.fieldKind);
456
+ const emptyChange = this.createEmptyFieldChange(fieldChange.fieldKind);
457
+ const [change1, change2] = areBaseFields
458
+ ? [fieldChange, emptyChange]
459
+ : [emptyChange, fieldChange];
524
460
 
525
- const composedField = this.composeFieldChanges(
526
- fieldId,
527
- baseFieldChange,
528
- emptyChange,
529
- genId,
530
- table,
531
- metadata,
532
- );
461
+ const composedField = this.composeFieldChanges(
462
+ fieldId,
463
+ change1,
464
+ change2,
465
+ genId,
466
+ table,
467
+ metadata,
468
+ );
533
469
 
534
- if (fieldId.nodeId === undefined) {
535
- composedFields.set(fieldId.field, composedField);
536
- return;
537
- }
470
+ if (fieldId.nodeId === undefined) {
471
+ composedFields.set(fieldId.field, composedField);
472
+ continue;
473
+ }
538
474
 
539
- const nodeId = normalizeNodeId(
540
- getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId,
541
- table.baseChange.nodeAliases,
542
- );
475
+ const nodeId =
476
+ getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId;
543
477
 
544
- // We clone the node changeset before mutating it, as it may be from one of the input changesets.
545
- const nodeChangeset: Mutable<NodeChangeset> = cloneNodeChangeset(
546
- nodeChangeFromId(composedNodes, table.baseChange.nodeAliases, nodeId),
547
- );
548
- setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
478
+ let nodeChangeset = nodeChangeFromId(composedNodes, nodeId);
479
+ if (!table.composedNodes.has(nodeChangeset)) {
480
+ nodeChangeset = cloneNodeChangeset(nodeChangeset);
481
+ setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
482
+ }
483
+
484
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
485
+ if (nodeChangeset.fieldChanges === undefined) {
486
+ nodeChangeset.fieldChanges = new Map();
487
+ }
549
488
 
550
- if (nodeChangeset.fieldChanges === undefined) {
551
- nodeChangeset.fieldChanges = new Map();
489
+ nodeChangeset.fieldChanges.set(fieldId.field, composedField);
552
490
  }
553
491
 
554
- nodeChangeset.fieldChanges.set(fieldId.field, composedField);
492
+ affectedFields.clear();
555
493
  }
556
494
 
557
495
  private composeFieldMaps(
@@ -570,18 +508,6 @@ export class ModularChangeFamily
570
508
  for (const [field, fieldChange1] of change1) {
571
509
  const fieldId: FieldId = { nodeId: parentId, field };
572
510
  const fieldChange2 = change2.get(field);
573
-
574
- const cachedComposedFieldChange =
575
- crossFieldTable.fieldToContext.get(fieldChange1)?.composedChange;
576
-
577
- if (fieldChange2 === undefined && cachedComposedFieldChange !== undefined) {
578
- // This can happen if the field was previous processed in `composeFieldWithNoNewChange`.
579
- // If `change2` does not have a change for this field, then without this check we would
580
- // lose the composed field change and instead simply have `change1`'s change.
581
- composedFields.set(field, cachedComposedFieldChange);
582
- continue;
583
- }
584
-
585
511
  const composedField =
586
512
  fieldChange2 === undefined
587
513
  ? fieldChange1
@@ -613,7 +539,7 @@ export class ModularChangeFamily
613
539
  * will be added to `crossFieldTable.pendingCompositions.nodeIdsToCompose`.
614
540
  *
615
541
  * Any fields which had cross-field information sent to them as part of this field composition
616
- * will be added to `affectedBaseFields` in `crossFieldTable.pendingCompositions`.
542
+ * will be added to either `affectedBaseFields` or `affectedNewFields` in `crossFieldTable.pendingCompositions`.
617
543
  *
618
544
  * Any composed `FieldChange` which is invalidated by new cross-field information will be added to `crossFieldTable.invalidatedFields`.
619
545
  */
@@ -632,14 +558,15 @@ export class ModularChangeFamily
632
558
  change2: change2Normalized,
633
559
  } = this.normalizeFieldChanges(change1, change2);
634
560
 
635
- const manager = new ComposeNodeManagerI(crossFieldTable, fieldId);
561
+ const manager = new ComposeManager(crossFieldTable, change1, fieldId);
636
562
 
637
563
  const composedChange = changeHandler.rebaser.compose(
638
564
  change1Normalized,
639
565
  change2Normalized,
640
566
  (child1, child2) => {
641
567
  if (child1 !== undefined && child2 !== undefined) {
642
- addNodesToCompose(crossFieldTable, child1, child2);
568
+ setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
569
+ crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
643
570
  }
644
571
  return child1 ?? child2 ?? fail(0xb23 /* Should not compose two undefined nodes */);
645
572
  },
@@ -665,19 +592,19 @@ export class ModularChangeFamily
665
592
  }
666
593
 
667
594
  private composeNodesById(
668
- change1: ModularChangeset,
669
- change2: ModularChangeset,
595
+ nodeChanges1: ChangeAtomIdBTree<NodeChangeset>,
596
+ nodeChanges2: ChangeAtomIdBTree<NodeChangeset>,
670
597
  composedNodes: ChangeAtomIdBTree<NodeChangeset>,
671
- composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
672
- composedAliases: ChangeAtomIdBTree<NodeId>,
598
+ composedNodeToParent: ChangeAtomIdBTree<FieldId>,
599
+ nodeAliases: ChangeAtomIdBTree<NodeId>,
673
600
  id1: NodeId,
674
601
  id2: NodeId,
675
602
  idAllocator: IdAllocator,
676
603
  crossFieldTable: ComposeTable,
677
604
  revisionMetadata: RevisionMetadataSource,
678
605
  ): void {
679
- const nodeChangeset1 = nodeChangeFromId(change1.nodeChanges, change1.nodeAliases, id1);
680
- const nodeChangeset2 = nodeChangeFromId(change2.nodeChanges, change2.nodeAliases, id2);
606
+ const nodeChangeset1 = nodeChangeFromId(nodeChanges1, id1);
607
+ const nodeChangeset2 = nodeChangeFromId(nodeChanges2, id2);
681
608
  const composedNodeChangeset = this.composeNodeChanges(
682
609
  id1,
683
610
  nodeChangeset1,
@@ -692,11 +619,13 @@ export class ModularChangeFamily
692
619
  if (!areEqualChangeAtomIds(id1, id2)) {
693
620
  composedNodes.delete([id2.revision, id2.localId]);
694
621
  composedNodeToParent.delete([id2.revision, id2.localId]);
695
- setInChangeAtomIdMap(composedAliases, id2, id1);
622
+ setInChangeAtomIdMap(nodeAliases, id2, id1);
696
623
 
697
624
  // We need to delete id1 to avoid forming a cycle in case id1 already had an alias.
698
- composedAliases.delete([id1.revision, id1.localId]);
625
+ nodeAliases.delete([id1.revision, id1.localId]);
699
626
  }
627
+
628
+ crossFieldTable.composedNodes.add(composedNodeChangeset);
700
629
  }
701
630
 
702
631
  private composeNodeChanges(
@@ -731,7 +660,7 @@ export class ModularChangeFamily
731
660
  revisionMetadata,
732
661
  );
733
662
 
734
- const composedNodeChange: Mutable<NodeChangeset> = {};
663
+ const composedNodeChange: NodeChangeset = {};
735
664
 
736
665
  if (composedFieldChanges.size > 0) {
737
666
  composedNodeChange.fieldChanges = composedFieldChanges;
@@ -786,14 +715,9 @@ export class ModularChangeFamily
786
715
  const genId: IdAllocator = idAllocatorFromMaxId(change.change.maxId ?? -1);
787
716
 
788
717
  const crossFieldTable: InvertTable = {
789
- change: change.change,
790
- entries: newChangeAtomIdRangeMap(),
718
+ ...newCrossFieldTable<FieldChange>(),
791
719
  originalFieldToContext: new Map(),
792
- invertRevision: revisionForInvert,
793
720
  invertedNodeToParent: brand(change.change.nodeToParent.clone()),
794
- invalidatedFields: new Set(),
795
- invertedRoots: invertRootTable(change.change, isRollback),
796
- attachToDetachId: newChangeAtomIdTransform(),
797
721
  };
798
722
  const { revInfos: oldRevInfos } = getRevInfoFromTaggedChanges([change]);
799
723
  const revisionMetadata = revisionMetadataSourceFromInfo(oldRevInfos);
@@ -834,7 +758,7 @@ export class ModularChangeFamily
834
758
  context !== undefined,
835
759
  0x851 /* Should have context for every invalidated field */,
836
760
  );
837
- const { invertedField } = context;
761
+ const { invertedField, fieldId } = context;
838
762
 
839
763
  const amendedChange = getChangeHandler(
840
764
  this.fieldKinds,
@@ -844,7 +768,7 @@ export class ModularChangeFamily
844
768
  isRollback,
845
769
  genId,
846
770
  revisionForInvert,
847
- new InvertNodeManagerI(crossFieldTable, context.fieldId),
771
+ new InvertManager(crossFieldTable, fieldChange, fieldId),
848
772
  revisionMetadata,
849
773
  );
850
774
  invertedField.change = brand(amendedChange);
@@ -853,13 +777,10 @@ export class ModularChangeFamily
853
777
 
854
778
  const crossFieldKeys = this.makeCrossFieldKeyTable(invertedFields, invertedNodes);
855
779
 
856
- this.processInvertRenames(crossFieldTable);
857
-
858
780
  return makeModularChangeset({
859
781
  fieldChanges: invertedFields,
860
782
  nodeChanges: invertedNodes,
861
783
  nodeToParent: crossFieldTable.invertedNodeToParent,
862
- rootNodes: crossFieldTable.invertedRoots,
863
784
  nodeAliases: change.change.nodeAliases,
864
785
  crossFieldKeys,
865
786
  maxId: genId.getMaxId(),
@@ -885,7 +806,7 @@ export class ModularChangeFamily
885
806
 
886
807
  for (const [field, fieldChange] of changes) {
887
808
  const fieldId = { nodeId: parentId, field };
888
- const manager = new InvertNodeManagerI(crossFieldTable, fieldId);
809
+ const manager = new InvertManager(crossFieldTable, fieldChange, fieldId);
889
810
  const invertedChange = getChangeHandler(
890
811
  this.fieldKinds,
891
812
  fieldChange.fieldKind,
@@ -922,7 +843,7 @@ export class ModularChangeFamily
922
843
  revisionMetadata: RevisionMetadataSource,
923
844
  revisionForInvert: RevisionTag,
924
845
  ): NodeChangeset {
925
- const inverse: Mutable<NodeChangeset> = {};
846
+ const inverse: NodeChangeset = {};
926
847
 
927
848
  // If the node has a constraint, it should be inverted to a node-exist-on-revert constraint. This ensure that if
928
849
  // the inverse is inverted again, the original input constraint will be restored.
@@ -952,17 +873,6 @@ export class ModularChangeFamily
952
873
  return inverse;
953
874
  }
954
875
 
955
- private processInvertRenames(table: InvertTable): void {
956
- for (const {
957
- start: newAttachId,
958
- value: originalDetachId,
959
- length,
960
- } of table.attachToDetachId.entries()) {
961
- // Note that the detach location is already set in `invertDetach`.
962
- addNodeRename(table.invertedRoots, originalDetachId, newAttachId, length, undefined);
963
- }
964
- }
965
-
966
876
  public rebase(
967
877
  taggedChange: TaggedChange<ModularChangeset>,
968
878
  potentiallyConflictedOver: TaggedChange<ModularChangeset>,
@@ -982,41 +892,17 @@ export class ModularChangeFamily
982
892
  const idState: IdAllocationState = { maxId };
983
893
  const genId: IdAllocator = idAllocatorFromState(idState);
984
894
 
985
- const affectedBaseFields: TupleBTree<FieldIdKey, boolean> = newTupleBTree();
986
- const nodesToRebase: [newChangeset: NodeId, baseChangeset: NodeId][] = [];
987
-
988
- const rebasedNodeToParent: ChangeAtomIdBTree<NodeLocation> = brand(
989
- change.nodeToParent.clone(),
990
- );
991
-
992
- const rebaseVersion = Math.max(
993
- change.rebaseVersion,
994
- over.change.rebaseVersion,
995
- ) as RebaseVersion;
996
-
997
- const rebasedRootNodes = rebaseRoots(
998
- change,
999
- over.change,
1000
- affectedBaseFields,
1001
- nodesToRebase,
1002
- rebasedNodeToParent,
1003
- rebaseVersion,
1004
- );
1005
895
  const crossFieldTable: RebaseTable = {
1006
- rebaseVersion,
1007
- entries: newDetachedEntryMap(),
896
+ ...newCrossFieldTable<FieldChange>(),
1008
897
  newChange: change,
1009
898
  baseChange: over.change,
1010
899
  baseFieldToContext: new Map(),
1011
- baseRoots: over.change.rootNodes,
1012
- rebasedRootNodes,
1013
900
  baseToRebasedNodeId: newTupleBTree(),
1014
901
  rebasedFields: new Set(),
1015
- rebasedNodeToParent,
1016
- rebasedDetachLocations: newChangeAtomIdRangeMap(),
1017
- movedDetaches: newChangeAtomIdRangeMap(),
902
+ rebasedNodeToParent: brand(change.nodeToParent.clone()),
903
+ rebasedCrossFieldKeys: change.crossFieldKeys.clone(),
1018
904
  nodeIdPairs: [],
1019
- affectedBaseFields,
905
+ affectedBaseFields: newTupleBTree(),
1020
906
  fieldsWithUnattachedChild: new Set(),
1021
907
  };
1022
908
 
@@ -1032,14 +918,13 @@ export class ModularChangeFamily
1032
918
  const rebasedNodes: ChangeAtomIdBTree<NodeChangeset> = brand(change.nodeChanges.clone());
1033
919
 
1034
920
  const rebasedFields = this.rebaseIntersectingFields(
1035
- nodesToRebase,
1036
921
  crossFieldTable,
1037
922
  rebasedNodes,
1038
923
  genId,
1039
924
  rebaseMetadata,
1040
925
  );
1041
926
 
1042
- this.rebaseInvalidatedFields(
927
+ this.rebaseInvalidatedElements(
1043
928
  rebasedFields,
1044
929
  rebasedNodes,
1045
930
  crossFieldTable,
@@ -1047,8 +932,6 @@ export class ModularChangeFamily
1047
932
  genId,
1048
933
  );
1049
934
 
1050
- fixupRebasedDetachLocations(crossFieldTable);
1051
-
1052
935
  const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
1053
936
  const revertConstraintState = newConstraintState(
1054
937
  change.constraintViolationCountOnRevert ?? 0,
@@ -1060,52 +943,21 @@ export class ModularChangeFamily
1060
943
  constraintState.violationCount += 1;
1061
944
  }
1062
945
 
1063
- this.updateConstraints(
946
+ this.updateConstraintsForFields(
1064
947
  rebasedFields,
1065
- rebasedNodes,
1066
- rebasedRootNodes,
948
+ NodeAttachState.Attached,
949
+ NodeAttachState.Attached,
1067
950
  constraintState,
1068
951
  revertConstraintState,
1069
- );
1070
-
1071
- const fieldsWithRootMoves = getFieldsWithRootMoves(
1072
- crossFieldTable.rebasedRootNodes,
1073
- change.nodeAliases,
1074
- );
1075
-
1076
- const fieldToRootChanges = getFieldToRootChanges(
1077
- crossFieldTable.rebasedRootNodes,
1078
- change.nodeAliases,
952
+ rebasedNodes,
1079
953
  );
1080
954
 
1081
955
  const rebased = makeModularChangeset({
1082
- fieldChanges: this.pruneFieldMap(
1083
- rebasedFields,
1084
- undefined,
1085
- rebasedNodes,
1086
- crossFieldTable.rebasedNodeToParent,
1087
- change.nodeAliases,
1088
- crossFieldTable.rebasedRootNodes,
1089
- fieldsWithRootMoves,
1090
- fieldToRootChanges,
1091
- ),
956
+ fieldChanges: this.pruneFieldMap(rebasedFields, rebasedNodes),
1092
957
  nodeChanges: rebasedNodes,
1093
958
  nodeToParent: crossFieldTable.rebasedNodeToParent,
1094
- rootNodes: this.pruneRoots(
1095
- crossFieldTable.rebasedRootNodes,
1096
- rebasedNodes,
1097
- crossFieldTable.rebasedNodeToParent,
1098
- change.nodeAliases,
1099
- fieldsWithRootMoves,
1100
- fieldToRootChanges,
1101
- ),
1102
- // TODO: Do we need to include aliases for node changesets added during rebasing?
1103
959
  nodeAliases: change.nodeAliases,
1104
- crossFieldKeys: rebaseCrossFieldKeys(
1105
- change.crossFieldKeys,
1106
- crossFieldTable.movedDetaches,
1107
- crossFieldTable.rebasedDetachLocations,
1108
- ),
960
+ crossFieldKeys: crossFieldTable.rebasedCrossFieldKeys,
1109
961
  maxId: idState.maxId,
1110
962
  revisions: change.revisions,
1111
963
  constraintViolationCount: constraintState.violationCount,
@@ -1115,18 +967,14 @@ export class ModularChangeFamily
1115
967
  builds: change.builds,
1116
968
  destroys: change.destroys,
1117
969
  refreshers: change.refreshers,
1118
- rebaseVersion,
1119
970
  });
1120
971
 
1121
- // XXX: This is an expensive assert which should be disabled before merging.
1122
- validateChangeset(rebased, this.fieldKinds);
1123
972
  return rebased;
1124
973
  }
1125
974
 
1126
975
  // This performs a first pass on all fields which have both new and base changes.
1127
976
  // TODO: Can we also handle additional passes in this method?
1128
977
  private rebaseIntersectingFields(
1129
- rootChanges: [newChangeset: NodeId, baseChangeset: NodeId][],
1130
978
  crossFieldTable: RebaseTable,
1131
979
  rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
1132
980
  genId: IdAllocator,
@@ -1143,18 +991,6 @@ export class ModularChangeFamily
1143
991
  metadata,
1144
992
  );
1145
993
 
1146
- for (const [newChildChange, baseChildChange] of rootChanges) {
1147
- const rebasedNode = this.rebaseNodeChange(
1148
- newChildChange,
1149
- baseChildChange,
1150
- genId,
1151
- crossFieldTable,
1152
- metadata,
1153
- );
1154
-
1155
- setInChangeAtomIdMap(rebasedNodes, newChildChange, rebasedNode);
1156
- }
1157
-
1158
994
  // This loop processes all fields which have both base and new changes.
1159
995
  // Note that the call to `rebaseNodeChange` can add entries to `crossFieldTable.nodeIdPairs`.
1160
996
  for (const [newId, baseId, _attachState] of crossFieldTable.nodeIdPairs) {
@@ -1172,150 +1008,137 @@ export class ModularChangeFamily
1172
1008
  return rebasedFields;
1173
1009
  }
1174
1010
 
1175
- private rebaseFieldWithoutNewChanges(
1176
- baseFieldChange: FieldChange,
1177
- baseFieldId: FieldId,
1178
- crossFieldTable: RebaseTable,
1011
+ // This processes fields which have no new changes but have been invalidated by another field.
1012
+ private rebaseFieldsWithoutNewChanges(
1179
1013
  rebasedFields: FieldChangeMap,
1180
1014
  rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
1015
+ crossFieldTable: RebaseTable,
1181
1016
  genId: IdAllocator,
1182
1017
  metadata: RebaseRevisionMetadata,
1183
-
1184
- /**
1185
- * The ID of a node in `baseFieldChange` which should be included in the rebased field change.
1186
- */
1187
- baseNodeId?: NodeId,
1188
1018
  ): void {
1189
- // This field has no changes in the new changeset, otherwise it would have been added to
1190
- // `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
1191
- const rebaseChild = (
1192
- child: NodeId | undefined,
1193
- baseChild: NodeId | undefined,
1194
- stateChange: NodeAttachState | undefined,
1195
- ): NodeId | undefined => {
1196
- assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
1197
- if (baseChild === undefined || baseNodeId === undefined) {
1198
- return undefined;
1199
- }
1019
+ const baseChange = crossFieldTable.baseChange;
1020
+ for (const [revision, localId, fieldKey] of crossFieldTable.affectedBaseFields.keys()) {
1021
+ const baseNodeId =
1022
+ localId === undefined
1023
+ ? undefined
1024
+ : normalizeNodeId({ revision, localId }, baseChange.nodeAliases);
1200
1025
 
1201
- return areEqualChangeAtomIds(
1202
- normalizeNodeId(baseChild, crossFieldTable.baseChange.nodeAliases),
1026
+ const baseFieldChange = fieldMapFromNodeId(
1027
+ baseChange.fieldChanges,
1028
+ baseChange.nodeChanges,
1203
1029
  baseNodeId,
1204
- )
1205
- ? baseNodeId
1206
- : undefined;
1207
- };
1030
+ ).get(fieldKey);
1208
1031
 
1209
- const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
1210
- const fieldChange: FieldChange = {
1211
- ...baseFieldChange,
1212
- change: brand(handler.createEmpty()),
1213
- };
1032
+ assert(
1033
+ baseFieldChange !== undefined,
1034
+ 0x9c2 /* Cross field key registered for empty field */,
1035
+ );
1036
+ if (crossFieldTable.baseFieldToContext.has(baseFieldChange)) {
1037
+ // This field has already been processed because there were changes to rebase.
1038
+ continue;
1039
+ }
1214
1040
 
1215
- const rebasedNodeId =
1216
- baseFieldId.nodeId === undefined
1217
- ? undefined
1218
- : rebasedNodeIdFromBaseNodeId(crossFieldTable, baseFieldId.nodeId);
1041
+ // This field has no changes in the new changeset, otherwise it would have been added to
1042
+ // `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
1043
+ const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
1044
+ const fieldChange: FieldChange = {
1045
+ ...baseFieldChange,
1046
+ change: brand(handler.createEmpty()),
1047
+ };
1219
1048
 
1220
- const fieldId: FieldId = { nodeId: rebasedNodeId, field: baseFieldId.field };
1049
+ const rebasedNodeId =
1050
+ baseNodeId === undefined
1051
+ ? undefined
1052
+ : rebasedNodeIdFromBaseNodeId(crossFieldTable, baseNodeId);
1221
1053
 
1222
- const rebasedField: unknown = handler.rebaser.rebase(
1223
- fieldChange.change,
1224
- baseFieldChange.change,
1225
- rebaseChild,
1226
- genId,
1227
- new RebaseNodeManagerI(crossFieldTable, fieldId),
1228
- metadata,
1229
- crossFieldTable.rebaseVersion,
1230
- );
1054
+ const fieldId: FieldId = { nodeId: rebasedNodeId, field: fieldKey };
1055
+ const rebasedField: unknown = handler.rebaser.rebase(
1056
+ fieldChange.change,
1057
+ baseFieldChange.change,
1058
+ noNewChangesRebaseChild,
1059
+ genId,
1060
+ new RebaseManager(crossFieldTable, baseFieldChange, fieldId),
1061
+ metadata,
1062
+ );
1231
1063
 
1232
- const rebasedFieldChange: FieldChange = {
1233
- ...baseFieldChange,
1234
- change: brand(rebasedField),
1235
- };
1064
+ const rebasedFieldChange: FieldChange = {
1065
+ ...baseFieldChange,
1066
+ change: brand(rebasedField),
1067
+ };
1236
1068
 
1237
- const context: RebaseFieldContext = {
1238
- newChange: fieldChange,
1239
- baseChange: baseFieldChange,
1240
- rebasedChange: rebasedFieldChange,
1241
- fieldId,
1242
- baseNodeIds: newTupleBTree(),
1243
- };
1069
+ // TODO: Deduplicate
1070
+ crossFieldTable.baseFieldToContext.set(baseFieldChange, {
1071
+ newChange: fieldChange,
1072
+ baseChange: baseFieldChange,
1073
+ rebasedChange: rebasedFieldChange,
1074
+ fieldId,
1075
+ baseNodeIds: [],
1076
+ });
1077
+ crossFieldTable.rebasedFields.add(rebasedFieldChange);
1244
1078
 
1245
- if (baseNodeId !== undefined) {
1246
- setInChangeAtomIdMap(context.baseNodeIds, baseNodeId, true);
1079
+ this.attachRebasedField(
1080
+ rebasedFields,
1081
+ rebasedNodes,
1082
+ crossFieldTable,
1083
+ rebasedFieldChange,
1084
+ fieldId,
1085
+ genId,
1086
+ metadata,
1087
+ );
1247
1088
  }
1089
+ }
1248
1090
 
1249
- crossFieldTable.baseFieldToContext.set(baseFieldChange, context);
1250
-
1251
- crossFieldTable.rebasedFields.add(rebasedFieldChange);
1252
-
1253
- this.attachRebasedField(
1091
+ private rebaseInvalidatedElements(
1092
+ rebasedFields: FieldChangeMap,
1093
+ rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
1094
+ table: RebaseTable,
1095
+ metadata: RebaseRevisionMetadata,
1096
+ idAllocator: IdAllocator,
1097
+ ): void {
1098
+ this.rebaseFieldsWithoutNewChanges(
1254
1099
  rebasedFields,
1255
1100
  rebasedNodes,
1256
- crossFieldTable,
1257
- rebasedFieldChange,
1258
- fieldId,
1259
- genId,
1101
+ table,
1102
+ idAllocator,
1260
1103
  metadata,
1261
1104
  );
1105
+
1106
+ this.rebaseFieldsWithUnattachedChild(table, metadata, idAllocator);
1107
+ this.rebaseInvalidatedFields(table, metadata, idAllocator);
1262
1108
  }
1263
1109
 
1264
1110
  private rebaseInvalidatedFields(
1265
- rebasedFields: FieldChangeMap,
1266
- rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
1267
1111
  crossFieldTable: RebaseTable,
1268
1112
  rebaseMetadata: RebaseRevisionMetadata,
1269
1113
  genId: IdAllocator,
1270
1114
  ): void {
1271
- while (crossFieldTable.affectedBaseFields.size > 0) {
1272
- const baseFields = crossFieldTable.affectedBaseFields.clone();
1273
- crossFieldTable.affectedBaseFields.clear();
1274
-
1275
- for (const baseFieldIdKey of baseFields.keys()) {
1276
- const baseFieldId = normalizeFieldId(
1277
- fieldIdFromFieldIdKey(baseFieldIdKey),
1278
- crossFieldTable.baseChange.nodeAliases,
1279
- );
1280
-
1281
- const baseField = fieldChangeFromId(crossFieldTable.baseChange, baseFieldId);
1282
-
1283
- assert(
1284
- baseField !== undefined,
1285
- 0x9c2 /* Cross field key registered for empty field */,
1286
- );
1115
+ const fieldsToUpdate = crossFieldTable.invalidatedFields;
1116
+ crossFieldTable.invalidatedFields = new Set();
1117
+ for (const field of fieldsToUpdate) {
1118
+ this.rebaseInvalidatedField(field, crossFieldTable, rebaseMetadata, genId);
1119
+ }
1120
+ }
1287
1121
 
1288
- const context = crossFieldTable.baseFieldToContext.get(baseField);
1289
- if (context === undefined) {
1290
- this.rebaseFieldWithoutNewChanges(
1291
- baseField,
1292
- baseFieldId,
1293
- crossFieldTable,
1294
- rebasedFields,
1295
- rebasedNodes,
1296
- genId,
1297
- rebaseMetadata,
1298
- );
1299
- } else {
1300
- this.rebaseInvalidatedField(
1301
- baseField,
1302
- crossFieldTable,
1303
- context,
1304
- rebaseMetadata,
1305
- genId,
1306
- );
1307
- }
1308
- }
1122
+ private rebaseFieldsWithUnattachedChild(
1123
+ table: RebaseTable,
1124
+ metadata: RebaseRevisionMetadata,
1125
+ idAllocator: IdAllocator,
1126
+ ): void {
1127
+ for (const field of table.fieldsWithUnattachedChild) {
1128
+ table.invalidatedFields.delete(field);
1129
+ this.rebaseInvalidatedField(field, table, metadata, idAllocator, true);
1309
1130
  }
1310
1131
  }
1311
1132
 
1312
1133
  private rebaseInvalidatedField(
1313
1134
  baseField: FieldChange,
1314
1135
  crossFieldTable: RebaseTable,
1315
- context: RebaseFieldContext,
1316
1136
  rebaseMetadata: RebaseRevisionMetadata,
1317
1137
  genId: IdAllocator,
1138
+ allowInval = false,
1318
1139
  ): void {
1140
+ const context = crossFieldTable.baseFieldToContext.get(baseField);
1141
+ assert(context !== undefined, 0x852 /* Every field should have a context */);
1319
1142
  const {
1320
1143
  changeHandler,
1321
1144
  change1: fieldChangeset,
@@ -1330,28 +1153,25 @@ export class ModularChangeFamily
1330
1153
  return curr;
1331
1154
  }
1332
1155
 
1333
- if (base !== undefined && getFromChangeAtomIdMap(context.baseNodeIds, base) === true) {
1334
- return base;
1335
- }
1156
+ if (base !== undefined) {
1157
+ for (const id of context.baseNodeIds) {
1158
+ if (areEqualChangeAtomIds(base, id)) {
1159
+ return base;
1160
+ }
1161
+ }
1162
+ }
1336
1163
 
1337
1164
  return undefined;
1338
1165
  };
1339
1166
 
1340
- let allowInval = false;
1341
- if (crossFieldTable.fieldsWithUnattachedChild.has(baseField)) {
1342
- crossFieldTable.fieldsWithUnattachedChild.delete(baseField);
1343
- allowInval = true;
1344
- }
1345
-
1346
1167
  context.rebasedChange.change = brand(
1347
1168
  changeHandler.rebaser.rebase(
1348
1169
  fieldChangeset,
1349
1170
  baseChangeset,
1350
1171
  rebaseChild,
1351
1172
  genId,
1352
- new RebaseNodeManagerI(crossFieldTable, context.fieldId, allowInval),
1173
+ new RebaseManager(crossFieldTable, baseField, context.fieldId, allowInval),
1353
1174
  rebaseMetadata,
1354
- crossFieldTable.rebaseVersion,
1355
1175
  ),
1356
1176
  );
1357
1177
  }
@@ -1371,19 +1191,13 @@ export class ModularChangeFamily
1371
1191
  }
1372
1192
  const rebasedNode = getFromChangeAtomIdMap(rebasedNodes, nodeId);
1373
1193
  if (rebasedNode !== undefined) {
1374
- const updatedRebasedNode: Mutable<NodeChangeset> = cloneNodeChangeset(rebasedNode);
1375
- setInChangeAtomIdMap(rebasedNodes, nodeId, updatedRebasedNode);
1376
-
1377
- if (updatedRebasedNode.fieldChanges === undefined) {
1378
- updatedRebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
1194
+ if (rebasedNode.fieldChanges === undefined) {
1195
+ rebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
1379
1196
  return;
1380
1197
  }
1381
1198
 
1382
- assert(
1383
- !updatedRebasedNode.fieldChanges.has(fieldKey),
1384
- 0x9c4 /* Expected an empty field */,
1385
- );
1386
- updatedRebasedNode.fieldChanges.set(fieldKey, rebasedField);
1199
+ assert(!rebasedNode.fieldChanges.has(fieldKey), 0x9c4 /* Expected an empty field */);
1200
+ rebasedNode.fieldChanges.set(fieldKey, rebasedField);
1387
1201
  return;
1388
1202
  }
1389
1203
 
@@ -1394,14 +1208,14 @@ export class ModularChangeFamily
1394
1208
  setInChangeAtomIdMap(rebasedNodes, nodeId, newNode);
1395
1209
  setInChangeAtomIdMap(table.baseToRebasedNodeId, nodeId, nodeId);
1396
1210
 
1397
- const parentBase = getNodeParent(table.baseChange, nodeId);
1211
+ const parentFieldId = getParentFieldId(table.baseChange, nodeId);
1398
1212
 
1399
1213
  this.attachRebasedNode(
1400
1214
  rebasedFields,
1401
1215
  rebasedNodes,
1402
1216
  table,
1403
1217
  nodeId,
1404
- parentBase,
1218
+ parentFieldId,
1405
1219
  idAllocator,
1406
1220
  metadata,
1407
1221
  );
@@ -1412,100 +1226,65 @@ export class ModularChangeFamily
1412
1226
  rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
1413
1227
  table: RebaseTable,
1414
1228
  baseNodeId: NodeId,
1415
- parentBase: NodeLocation,
1229
+ parentFieldIdBase: FieldId,
1416
1230
  idAllocator: IdAllocator,
1417
1231
  metadata: RebaseRevisionMetadata,
1418
1232
  ): void {
1419
- if (parentBase.root !== undefined) {
1420
- const renamedRoot = firstAttachIdFromDetachId(
1421
- table.baseChange.rootNodes,
1422
- parentBase.root,
1423
- 1,
1424
- ).value;
1425
-
1426
- const attachField = table.baseChange.crossFieldKeys.getFirst(
1427
- { ...renamedRoot, target: CrossFieldTarget.Destination },
1428
- 1,
1429
- ).value;
1430
-
1431
- if (attachField === undefined) {
1432
- const baseDetachLocation = table.baseChange.rootNodes.detachLocations.getFirst(
1433
- parentBase.root,
1434
- 1,
1435
- ).value;
1436
-
1437
- assignRootChange(
1438
- table.rebasedRootNodes,
1439
- table.rebasedNodeToParent,
1440
- renamedRoot,
1441
- baseNodeId,
1442
- baseDetachLocation,
1443
- table.rebaseVersion,
1444
- );
1445
-
1446
- // We need to make sure the rebased changeset includes the detach location,
1447
- // so we add that field to `affectedBaseFields` unless it's already been processed.
1448
- if (
1449
- baseDetachLocation !== undefined &&
1450
- !table.baseFieldToContext.has(
1451
- fieldChangeFromId(table.baseChange, baseDetachLocation),
1452
- )
1453
- ) {
1454
- table.affectedBaseFields.set(fieldIdKeyFromFieldId(baseDetachLocation), true);
1455
- }
1456
- } else {
1457
- // The base change inserts this node into `attachField`, so the rebased change should represent this node there.
1458
- const normalizedAttachField = normalizeFieldId(
1459
- attachField,
1460
- table.baseChange.nodeAliases,
1461
- );
1462
-
1463
- const entry: DetachedNodeEntry = table.entries.getFirst(renamedRoot, 1).value ?? {};
1464
- table.entries.set(renamedRoot, 1, { ...entry, nodeChange: baseNodeId });
1465
- table.affectedBaseFields.set(fieldIdKeyFromFieldId(normalizedAttachField), true);
1466
- this.attachRebasedNode(
1467
- rebasedFields,
1468
- rebasedNodes,
1469
- table,
1470
- baseNodeId,
1471
- { field: normalizedAttachField },
1472
- idAllocator,
1473
- metadata,
1474
- );
1475
- }
1476
-
1477
- return;
1478
- }
1479
-
1480
- const parentFieldIdBase = parentBase.field;
1481
- const baseFieldChange = fieldChangeFromId(table.baseChange, parentFieldIdBase);
1233
+ const baseFieldChange = fieldChangeFromId(
1234
+ table.baseChange.fieldChanges,
1235
+ table.baseChange.nodeChanges,
1236
+ parentFieldIdBase,
1237
+ );
1482
1238
 
1483
1239
  const rebasedFieldId = rebasedFieldIdFromBaseId(table, parentFieldIdBase);
1484
- setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, { field: rebasedFieldId });
1240
+ setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, rebasedFieldId);
1485
1241
 
1486
1242
  const context = table.baseFieldToContext.get(baseFieldChange);
1487
1243
  if (context !== undefined) {
1488
1244
  // We've already processed this field.
1489
- // The new child node will be attached in the next pass.
1490
- // Note that adding to `fieldsWithUnattachedChild` allows that field to generate new invalidations,
1491
- // so to avoid invalidation cycles we make sure we only add to it once per new unattached child.
1492
- // This is done by checking whether `context.baseNodeIds` already contained `baseNodeId`.
1493
- if (setInChangeAtomIdMap(context.baseNodeIds, baseNodeId, true)) {
1494
- table.fieldsWithUnattachedChild.add(baseFieldChange);
1495
- table.affectedBaseFields.set(fieldIdKeyFromFieldId(parentFieldIdBase), true);
1496
- }
1245
+ // The new child node will be attached in rebaseFieldsWithUnattachedChild.
1246
+ context.baseNodeIds.push(baseNodeId);
1247
+ table.fieldsWithUnattachedChild.add(baseFieldChange);
1497
1248
  return;
1498
1249
  }
1499
1250
 
1500
- this.rebaseFieldWithoutNewChanges(
1501
- baseFieldChange,
1502
- parentFieldIdBase,
1503
- table,
1251
+ const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
1252
+
1253
+ const fieldChange: FieldChange = {
1254
+ ...baseFieldChange,
1255
+ change: brand(handler.createEmpty()),
1256
+ };
1257
+
1258
+ const rebasedChangeset = handler.rebaser.rebase(
1259
+ handler.createEmpty(),
1260
+ baseFieldChange.change,
1261
+ (_idNew, idBase) =>
1262
+ idBase !== undefined && areEqualChangeAtomIds(idBase, baseNodeId)
1263
+ ? baseNodeId
1264
+ : undefined,
1265
+ idAllocator,
1266
+ new RebaseManager(table, baseFieldChange, rebasedFieldId),
1267
+ metadata,
1268
+ );
1269
+
1270
+ const rebasedField: FieldChange = { ...baseFieldChange, change: brand(rebasedChangeset) };
1271
+ table.rebasedFields.add(rebasedField);
1272
+ table.baseFieldToContext.set(baseFieldChange, {
1273
+ newChange: fieldChange,
1274
+ baseChange: baseFieldChange,
1275
+ rebasedChange: rebasedField,
1276
+ fieldId: rebasedFieldId,
1277
+ baseNodeIds: [],
1278
+ });
1279
+
1280
+ this.attachRebasedField(
1504
1281
  rebasedFields,
1505
1282
  rebasedNodes,
1283
+ table,
1284
+ rebasedField,
1285
+ rebasedFieldId,
1506
1286
  idAllocator,
1507
1287
  metadata,
1508
- baseNodeId,
1509
1288
  );
1510
1289
  }
1511
1290
 
@@ -1544,7 +1323,7 @@ export class ModularChangeFamily
1544
1323
  change2: baseChangeset,
1545
1324
  } = this.normalizeFieldChanges(fieldChange, baseChange);
1546
1325
 
1547
- const manager = new RebaseNodeManagerI(crossFieldTable, fieldId);
1326
+ const manager = new RebaseManager(crossFieldTable, baseChange, fieldId);
1548
1327
 
1549
1328
  const rebasedField = changeHandler.rebaser.rebase(
1550
1329
  fieldChangeset,
@@ -1553,7 +1332,6 @@ export class ModularChangeFamily
1553
1332
  genId,
1554
1333
  manager,
1555
1334
  revisionMetadata,
1556
- crossFieldTable.rebaseVersion,
1557
1335
  );
1558
1336
 
1559
1337
  const rebasedFieldChange: FieldChange = {
@@ -1568,7 +1346,7 @@ export class ModularChangeFamily
1568
1346
  newChange: fieldChange,
1569
1347
  rebasedChange: rebasedFieldChange,
1570
1348
  fieldId,
1571
- baseNodeIds: newTupleBTree(),
1349
+ baseNodeIds: [],
1572
1350
  });
1573
1351
 
1574
1352
  crossFieldTable.rebasedFields.add(rebasedFieldChange);
@@ -1584,16 +1362,8 @@ export class ModularChangeFamily
1584
1362
  crossFieldTable: RebaseTable,
1585
1363
  revisionMetadata: RebaseRevisionMetadata,
1586
1364
  ): NodeChangeset {
1587
- const change = nodeChangeFromId(
1588
- crossFieldTable.newChange.nodeChanges,
1589
- crossFieldTable.newChange.nodeAliases,
1590
- newId,
1591
- );
1592
- const over = nodeChangeFromId(
1593
- crossFieldTable.baseChange.nodeChanges,
1594
- crossFieldTable.baseChange.nodeAliases,
1595
- baseId,
1596
- );
1365
+ const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, newId);
1366
+ const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, baseId);
1597
1367
 
1598
1368
  const baseMap: FieldChangeMap = over?.fieldChanges ?? new Map();
1599
1369
 
@@ -1609,7 +1379,7 @@ export class ModularChangeFamily
1609
1379
  )
1610
1380
  : change.fieldChanges;
1611
1381
 
1612
- const rebasedChange: Mutable<NodeChangeset> = {};
1382
+ const rebasedChange: NodeChangeset = {};
1613
1383
 
1614
1384
  if (fieldChanges !== undefined && fieldChanges.size > 0) {
1615
1385
  rebasedChange.fieldChanges = fieldChanges;
@@ -1627,37 +1397,6 @@ export class ModularChangeFamily
1627
1397
  return rebasedChange;
1628
1398
  }
1629
1399
 
1630
- private updateConstraints(
1631
- rebasedFields: FieldChangeMap,
1632
- rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
1633
- rebasedRoots: RootNodeTable,
1634
- constraintState: ConstraintState,
1635
- revertConstraintState: ConstraintState,
1636
- ): void {
1637
- this.updateConstraintsForFields(
1638
- rebasedFields,
1639
- NodeAttachState.Attached,
1640
- NodeAttachState.Attached,
1641
- constraintState,
1642
- revertConstraintState,
1643
- rebasedNodes,
1644
- );
1645
-
1646
- for (const [_detachId, nodeId] of rebasedRoots.nodeChanges.entries()) {
1647
- // XXX: This is incorrect if the rebased changeset attaches the node.
1648
- // Efficiently computing whether the changeset attaches the node would require maintaining a mapping from node ID to attach ID.
1649
- const detachedInOutput = true;
1650
- this.updateConstraintsForNode(
1651
- nodeId,
1652
- NodeAttachState.Detached,
1653
- detachedInOutput ? NodeAttachState.Detached : NodeAttachState.Attached,
1654
- rebasedNodes,
1655
- constraintState,
1656
- revertConstraintState,
1657
- );
1658
- }
1659
- }
1660
-
1661
1400
  private updateConstraintsForFields(
1662
1401
  fields: FieldChangeMap,
1663
1402
  parentInputAttachState: NodeAttachState,
@@ -1668,18 +1407,20 @@ export class ModularChangeFamily
1668
1407
  ): void {
1669
1408
  for (const field of fields.values()) {
1670
1409
  const handler = getChangeHandler(this.fieldKinds, field.fieldKind);
1671
- for (const [nodeId] of handler.getNestedChanges(field.change)) {
1672
- // XXX: This is incorrect if the rebased changeset detaches this node.
1673
- // Efficiently computing whether the changeset detaches the node would require maintaining a mapping from node ID to detach ID.
1674
- const isOutputDetached = false;
1410
+ for (const [nodeId, inputIndex, outputIndex] of handler.getNestedChanges(field.change)) {
1411
+ const isInputDetached = inputIndex === undefined;
1412
+ const inputAttachState =
1413
+ parentInputAttachState === NodeAttachState.Detached || isInputDetached
1414
+ ? NodeAttachState.Detached
1415
+ : NodeAttachState.Attached;
1416
+ const isOutputDetached = outputIndex === undefined;
1675
1417
  const outputAttachState =
1676
1418
  parentOutputAttachState === NodeAttachState.Detached || isOutputDetached
1677
1419
  ? NodeAttachState.Detached
1678
1420
  : NodeAttachState.Attached;
1679
-
1680
1421
  this.updateConstraintsForNode(
1681
1422
  nodeId,
1682
- parentInputAttachState,
1423
+ inputAttachState,
1683
1424
  outputAttachState,
1684
1425
  nodes,
1685
1426
  constraintState,
@@ -1697,15 +1438,12 @@ export class ModularChangeFamily
1697
1438
  constraintState: ConstraintState,
1698
1439
  revertConstraintState: ConstraintState,
1699
1440
  ): void {
1700
- const node = getFromChangeAtomIdMap(nodes, nodeId) ?? fail(0xb24 /* Unknown node ID */);
1701
-
1702
- const updatedNode: Mutable<NodeChangeset> = { ...node };
1703
- setInChangeAtomIdMap(nodes, nodeId, updatedNode);
1704
-
1441
+ const node =
1442
+ nodes.get([nodeId.revision, nodeId.localId]) ?? fail(0xb24 /* Unknown node ID */);
1705
1443
  if (node.nodeExistsConstraint !== undefined) {
1706
1444
  const isNowViolated = inputAttachState === NodeAttachState.Detached;
1707
1445
  if (node.nodeExistsConstraint.violated !== isNowViolated) {
1708
- updatedNode.nodeExistsConstraint = {
1446
+ node.nodeExistsConstraint = {
1709
1447
  ...node.nodeExistsConstraint,
1710
1448
  violated: isNowViolated,
1711
1449
  };
@@ -1715,7 +1453,7 @@ export class ModularChangeFamily
1715
1453
  if (node.nodeExistsConstraintOnRevert !== undefined) {
1716
1454
  const isNowViolated = outputAttachState === NodeAttachState.Detached;
1717
1455
  if (node.nodeExistsConstraintOnRevert.violated !== isNowViolated) {
1718
- updatedNode.nodeExistsConstraintOnRevert = {
1456
+ node.nodeExistsConstraintOnRevert = {
1719
1457
  ...node.nodeExistsConstraintOnRevert,
1720
1458
  violated: isNowViolated,
1721
1459
  };
@@ -1737,13 +1475,7 @@ export class ModularChangeFamily
1737
1475
 
1738
1476
  private pruneFieldMap(
1739
1477
  changeset: FieldChangeMap | undefined,
1740
- parentId: NodeId | undefined,
1741
1478
  nodeMap: ChangeAtomIdBTree<NodeChangeset>,
1742
- nodeToParent: ChangeAtomIdBTree<NodeLocation>,
1743
- aliases: ChangeAtomIdBTree<NodeId>,
1744
- roots: RootNodeTable,
1745
- fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
1746
- fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
1747
1479
  ): FieldChangeMap | undefined {
1748
1480
  if (changeset === undefined) {
1749
1481
  return undefined;
@@ -1754,48 +1486,10 @@ export class ModularChangeFamily
1754
1486
  const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
1755
1487
 
1756
1488
  const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) =>
1757
- this.pruneNodeChange(
1758
- nodeId,
1759
- nodeMap,
1760
- nodeToParent,
1761
- aliases,
1762
- roots,
1763
- fieldsWithRootMoves,
1764
- fieldsToRootChanges,
1765
- ),
1489
+ this.pruneNodeChange(nodeId, nodeMap),
1766
1490
  );
1767
1491
 
1768
- const fieldId: FieldId = { nodeId: parentId, field };
1769
- const fieldIdKey = fieldIdKeyFromFieldId(fieldId);
1770
- const rootsWithChanges = fieldsToRootChanges.get(fieldIdKey) ?? [];
1771
- let hasRootWithNodeChange = false;
1772
- for (const rootId of rootsWithChanges) {
1773
- const nodeId =
1774
- getFromChangeAtomIdMap(roots.nodeChanges, rootId) ?? fail("No root change found");
1775
-
1776
- const isRootChangeEmpty =
1777
- this.pruneNodeChange(
1778
- nodeId,
1779
- nodeMap,
1780
- nodeToParent,
1781
- aliases,
1782
- roots,
1783
- fieldsWithRootMoves,
1784
- fieldsToRootChanges,
1785
- ) === undefined;
1786
-
1787
- if (isRootChangeEmpty) {
1788
- roots.nodeChanges.delete([rootId.revision, rootId.localId]);
1789
- tryRemoveDetachLocation(roots, rootId, 1);
1790
- } else {
1791
- hasRootWithNodeChange = true;
1792
- }
1793
- }
1794
-
1795
- const hasRootChanges =
1796
- hasRootWithNodeChange || fieldsWithRootMoves.get(fieldIdKey) === true;
1797
-
1798
- if (!handler.isEmpty(prunedFieldChangeset) || hasRootChanges) {
1492
+ if (!handler.isEmpty(prunedFieldChangeset)) {
1799
1493
  prunedChangeset.set(field, { ...fieldChange, change: brand(prunedFieldChangeset) });
1800
1494
  }
1801
1495
  }
@@ -1803,65 +1497,15 @@ export class ModularChangeFamily
1803
1497
  return prunedChangeset.size > 0 ? prunedChangeset : undefined;
1804
1498
  }
1805
1499
 
1806
- private pruneRoots(
1807
- roots: RootNodeTable,
1808
- nodeMap: ChangeAtomIdBTree<NodeChangeset>,
1809
- nodeToParent: ChangeAtomIdBTree<NodeLocation>,
1810
- aliases: ChangeAtomIdBTree<NodeId>,
1811
- fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
1812
- fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
1813
- ): RootNodeTable {
1814
- const pruned: RootNodeTable = { ...roots, nodeChanges: newTupleBTree() };
1815
- for (const [rootIdKey, nodeId] of roots.nodeChanges.entries()) {
1816
- const rootId: ChangeAtomId = { revision: rootIdKey[0], localId: rootIdKey[1] };
1817
- const hasDetachLocation = roots.detachLocations.getFirst(rootId, 1).value !== undefined;
1818
-
1819
- // If the root has a detach location it should be pruned by recursion when pruning the field it was detached from.
1820
- const prunedId = hasDetachLocation
1821
- ? nodeId
1822
- : this.pruneNodeChange(
1823
- nodeId,
1824
- nodeMap,
1825
- nodeToParent,
1826
- aliases,
1827
- roots,
1828
- fieldsWithRootMoves,
1829
- fieldsToRootChanges,
1830
- );
1831
-
1832
- if (prunedId !== undefined) {
1833
- pruned.nodeChanges.set(rootIdKey, prunedId);
1834
- }
1835
-
1836
- tryRemoveDetachLocation(pruned, rootId, 1);
1837
- }
1838
-
1839
- return pruned;
1840
- }
1841
-
1842
1500
  private pruneNodeChange(
1843
1501
  nodeId: NodeId,
1844
- nodes: ChangeAtomIdBTree<NodeChangeset>,
1845
- nodeToParent: ChangeAtomIdBTree<NodeLocation>,
1846
- aliases: ChangeAtomIdBTree<NodeId>,
1847
- roots: RootNodeTable,
1848
- fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
1849
- fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
1502
+ nodeMap: ChangeAtomIdBTree<NodeChangeset>,
1850
1503
  ): NodeId | undefined {
1851
- const changeset = nodeChangeFromId(nodes, aliases, nodeId);
1504
+ const changeset = nodeChangeFromId(nodeMap, nodeId);
1852
1505
  const prunedFields =
1853
1506
  changeset.fieldChanges === undefined
1854
1507
  ? undefined
1855
- : this.pruneFieldMap(
1856
- changeset.fieldChanges,
1857
- nodeId,
1858
- nodes,
1859
- nodeToParent,
1860
- aliases,
1861
- roots,
1862
- fieldsWithRootMoves,
1863
- fieldsToRootChanges,
1864
- );
1508
+ : this.pruneFieldMap(changeset.fieldChanges, nodeMap);
1865
1509
 
1866
1510
  const prunedChange = { ...changeset, fieldChanges: prunedFields };
1867
1511
  if (prunedChange.fieldChanges === undefined) {
@@ -1869,27 +1513,17 @@ export class ModularChangeFamily
1869
1513
  }
1870
1514
 
1871
1515
  if (isEmptyNodeChangeset(prunedChange)) {
1872
- const nodeIdKey: [RevisionTag | undefined, ChangesetLocalId] = [
1873
- nodeId.revision,
1874
- nodeId.localId,
1875
- ];
1876
-
1877
- // TODO: Shouldn't we also delete all aliases associated with this node?
1878
- nodes.delete(nodeIdKey);
1879
- nodeToParent.delete(nodeIdKey);
1516
+ nodeMap.delete([nodeId.revision, nodeId.localId]);
1880
1517
  return undefined;
1881
1518
  } else {
1882
- setInChangeAtomIdMap(nodes, nodeId, prunedChange);
1519
+ setInChangeAtomIdMap(nodeMap, nodeId, prunedChange);
1883
1520
  return nodeId;
1884
1521
  }
1885
1522
  }
1886
1523
 
1887
1524
  public getRevisions(change: ModularChangeset): Set<RevisionTag | undefined> {
1888
- if (change.revisions === undefined || change.revisions.length === 0) {
1889
- return new Set([undefined]);
1890
- }
1891
1525
  const aggregated: Set<RevisionTag | undefined> = new Set();
1892
- for (const revInfo of change.revisions) {
1526
+ for (const revInfo of change.revisions ?? [{ revision: undefined }]) {
1893
1527
  aggregated.add(revInfo.revision);
1894
1528
  }
1895
1529
  return aggregated;
@@ -1906,11 +1540,8 @@ export class ModularChangeFamily
1906
1540
  const updatedNodeToParent = replaceIdMapRevisions(
1907
1541
  change.nodeToParent,
1908
1542
  replacer,
1909
- (location) =>
1910
- replaceNodeLocationRevision(
1911
- normalizeNodeLocation(location, change.nodeAliases),
1912
- replacer,
1913
- ),
1543
+ (fieldId) =>
1544
+ replaceFieldIdRevision(normalizeFieldId(fieldId, change.nodeAliases), replacer),
1914
1545
  );
1915
1546
 
1916
1547
  const updated: Mutable<ModularChangeset> = {
@@ -1918,7 +1549,6 @@ export class ModularChangeFamily
1918
1549
  fieldChanges: updatedFields,
1919
1550
  nodeChanges: updatedNodes,
1920
1551
  nodeToParent: updatedNodeToParent,
1921
- rootNodes: replaceRootTableRevision(change.rootNodes, replacer, change.nodeAliases),
1922
1552
 
1923
1553
  // We've updated all references to old node IDs, so we no longer need an alias table.
1924
1554
  nodeAliases: newTupleBTree(),
@@ -1982,7 +1612,7 @@ export class ModularChangeFamily
1982
1612
  fields: FieldChangeMap,
1983
1613
  nodes: ChangeAtomIdBTree<NodeChangeset>,
1984
1614
  ): CrossFieldKeyTable {
1985
- const keys: CrossFieldKeyTable = newCrossFieldRangeTable();
1615
+ const keys: CrossFieldKeyTable = newCrossFieldKeyTable();
1986
1616
  this.populateCrossFieldKeyTableForFieldMap(keys, fields, undefined);
1987
1617
  nodes.forEachPair(([revision, localId], node) => {
1988
1618
  if (node.fieldChanges !== undefined) {
@@ -2023,6 +1653,63 @@ export class ModularChangeFamily
2023
1653
  return { fieldKind, change: brand(emptyChange) };
2024
1654
  }
2025
1655
 
1656
+ public validateChangeset(change: ModularChangeset): void {
1657
+ let numNodes = this.validateFieldChanges(change, change.fieldChanges, undefined);
1658
+
1659
+ for (const [[revision, localId], node] of change.nodeChanges.entries()) {
1660
+ if (node.fieldChanges === undefined) {
1661
+ continue;
1662
+ }
1663
+
1664
+ const nodeId: NodeId = { revision, localId };
1665
+ const numChildren = this.validateFieldChanges(change, node.fieldChanges, nodeId);
1666
+
1667
+ numNodes += numChildren;
1668
+ }
1669
+
1670
+ assert(
1671
+ numNodes === change.nodeChanges.size,
1672
+ 0xa4d /* Node table contains unparented nodes */,
1673
+ );
1674
+ }
1675
+
1676
+ /**
1677
+ * Asserts that each child and cross field key in each field has a correct entry in
1678
+ * `nodeToParent` or `crossFieldKeyTable`.
1679
+ * @returns the number of children found.
1680
+ */
1681
+ private validateFieldChanges(
1682
+ change: ModularChangeset,
1683
+ fieldChanges: FieldChangeMap,
1684
+ nodeParent: NodeId | undefined,
1685
+ ): number {
1686
+ let numChildren = 0;
1687
+ for (const [field, fieldChange] of fieldChanges.entries()) {
1688
+ const fieldId = { nodeId: nodeParent, field };
1689
+ const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
1690
+ for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
1691
+ const parentFieldId = getParentFieldId(change, child);
1692
+ assert(
1693
+ areEqualFieldIds(parentFieldId, fieldId),
1694
+ 0xa4e /* Inconsistent node parentage */,
1695
+ );
1696
+ numChildren += 1;
1697
+ }
1698
+
1699
+ for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
1700
+ const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
1701
+ assert(
1702
+ fields.length === 1 &&
1703
+ fields[0] !== undefined &&
1704
+ areEqualFieldIds(fields[0], fieldId),
1705
+ 0xa4f /* Inconsistent cross field keys */,
1706
+ );
1707
+ }
1708
+ }
1709
+
1710
+ return numChildren;
1711
+ }
1712
+
2026
1713
  private getEffectiveChange(change: ModularChangeset): ModularChangeset {
2027
1714
  if (hasConflicts(change)) {
2028
1715
  return this.muteChange(change);
@@ -2036,8 +1723,7 @@ export class ModularChangeFamily
2036
1723
  private muteChange(change: ModularChangeset): ModularChangeset {
2037
1724
  const muted: Mutable<ModularChangeset> = {
2038
1725
  ...change,
2039
- rootNodes: muteRootChanges(change.rootNodes),
2040
- crossFieldKeys: newCrossFieldRangeTable(),
1726
+ crossFieldKeys: newCrossFieldKeyTable(),
2041
1727
  fieldChanges: this.muteFieldChanges(change.fieldChanges),
2042
1728
  nodeChanges: brand(change.nodeChanges.mapValues((v) => this.muteNodeChange(v))),
2043
1729
  };
@@ -2074,7 +1760,7 @@ function replaceCrossFieldKeyTableRevisions(
2074
1760
  replacer: RevisionReplacer,
2075
1761
  nodeAliases: ChangeAtomIdBTree<NodeId>,
2076
1762
  ): CrossFieldKeyTable {
2077
- const updated: CrossFieldKeyTable = newCrossFieldRangeTable();
1763
+ const updated: CrossFieldKeyTable = newCrossFieldKeyTable();
2078
1764
  for (const entry of table.entries()) {
2079
1765
  const key = entry.start;
2080
1766
  const updatedKey: CrossFieldKey = replacer.getUpdatedAtomId(key);
@@ -2181,20 +1867,6 @@ function composeBuildsDestroysAndRefreshers(
2181
1867
  }
2182
1868
  }
2183
1869
 
2184
- // 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.
2185
- if (change1.builds !== undefined && change2.refreshers !== undefined) {
2186
- for (const [key, chunk] of change2.refreshers.entries()) {
2187
- assert(chunk.topLevelLength === 1, "Expected refresher chunk to have length 1");
2188
- const match = change1.builds.getPairOrNextLower(key);
2189
- if (match !== undefined) {
2190
- const [buildKey, buildChunk] = match;
2191
- if (buildKey[0] === key[0] && buildKey[1] + buildChunk.topLevelLength > key[1]) {
2192
- allRefreshers.delete(key);
2193
- }
2194
- }
2195
- }
2196
- }
2197
-
2198
1870
  return { allBuilds, allDestroys, allRefreshers };
2199
1871
  }
2200
1872
 
@@ -2226,77 +1898,30 @@ export function* relevantRemovedRoots(
2226
1898
  change: ModularChangeset,
2227
1899
  fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
2228
1900
  ): Iterable<DeltaDetachedNodeId> {
2229
- const rootIds: ChangeAtomIdRangeMap<boolean> = newChangeAtomIdRangeMap();
2230
- addAttachesToSet(change, rootIds);
2231
- addRenamesToSet(change, rootIds);
2232
-
2233
- for (const [[revision, localId]] of change.rootNodes.nodeChanges.entries()) {
2234
- rootIds.set({ revision, localId }, 1, true);
2235
- }
2236
-
2237
- for (const entry of rootIds.entries()) {
2238
- for (let offset = 0; offset < entry.length; offset++) {
2239
- const detachId = offsetChangeAtomId(entry.start, offset);
2240
- yield makeDetachedNodeId(detachId.revision, detachId.localId);
2241
- }
2242
- }
2243
- }
2244
-
2245
- export function* getBuildIds(change: ModularChangeset): Iterable<DeltaDetachedNodeId> {
2246
- if (change.builds !== undefined) {
2247
- for (const [[revision, localId]] of change.builds.entries()) {
2248
- yield makeDetachedNodeId(revision, localId);
2249
- }
2250
- }
1901
+ yield* relevantRemovedRootsFromFields(change.fieldChanges, change.nodeChanges, fieldKinds);
2251
1902
  }
2252
1903
 
2253
- function addAttachesToSet(
2254
- change: ModularChangeset,
2255
- rootIds: ChangeAtomIdRangeMap<boolean>,
2256
- ): void {
2257
- // This includes each attach which does not have a corresponding detach.
2258
- for (const entry of change.crossFieldKeys.entries()) {
2259
- if (entry.start.target !== CrossFieldTarget.Destination) {
2260
- continue;
2261
- }
2262
-
2263
- for (const detachIdEntry of change.rootNodes.newToOldId.getAll2(
2264
- entry.start,
2265
- entry.length,
2266
- )) {
2267
- const detachId =
2268
- detachIdEntry.value ?? offsetChangeAtomId(entry.start, detachIdEntry.offset);
2269
- for (const detachEntry of change.crossFieldKeys.getAll2(
2270
- { ...detachId, target: CrossFieldTarget.Source },
2271
- detachIdEntry.length,
2272
- )) {
2273
- if (detachEntry.value === undefined) {
2274
- rootIds.set(
2275
- offsetChangeAtomId(detachId, detachEntry.offset),
2276
- detachEntry.length,
2277
- true,
2278
- );
2279
- }
2280
- }
2281
- }
1904
+ function* relevantRemovedRootsFromNode(
1905
+ node: NodeId,
1906
+ nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
1907
+ fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
1908
+ ): Iterable<DeltaDetachedNodeId> {
1909
+ const nodeChangeset = nodeChangeFromId(nodeChanges, node);
1910
+ if (nodeChangeset.fieldChanges !== undefined) {
1911
+ yield* relevantRemovedRootsFromFields(nodeChangeset.fieldChanges, nodeChanges, fieldKinds);
2282
1912
  }
2283
1913
  }
2284
1914
 
2285
- function addRenamesToSet(
2286
- change: ModularChangeset,
2287
- rootIds: ChangeAtomIdRangeMap<boolean>,
2288
- ): void {
2289
- for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
2290
- for (const detachEntry of change.crossFieldKeys.getAll2(
2291
- { ...renameEntry.start, target: CrossFieldTarget.Source },
2292
- renameEntry.length,
2293
- )) {
2294
- // We only want to include renames of nodes which are detached in the input context of the changeset.
2295
- // So if there is a detach for the node, the rename is not relevant.
2296
- if (detachEntry.value === undefined) {
2297
- rootIds.set(renameEntry.start, renameEntry.length, true);
2298
- }
2299
- }
1915
+ function* relevantRemovedRootsFromFields(
1916
+ change: FieldChangeMap,
1917
+ nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
1918
+ fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
1919
+ ): Iterable<DeltaDetachedNodeId> {
1920
+ const delegate = (node: NodeId): Iterable<DeltaDetachedNodeId> =>
1921
+ relevantRemovedRootsFromNode(node, nodeChanges, fieldKinds);
1922
+ for (const [_, fieldChange] of change) {
1923
+ const handler = getChangeHandler(fieldKinds, fieldChange.fieldKind);
1924
+ yield* handler.relevantRemovedRoots(fieldChange.change, delegate);
2300
1925
  }
2301
1926
  }
2302
1927
 
@@ -2365,7 +1990,6 @@ export function updateRefreshers(
2365
1990
  constraintViolationCountOnRevert,
2366
1991
  builds,
2367
1992
  destroys,
2368
- rootNodes,
2369
1993
  } = change;
2370
1994
 
2371
1995
  return makeModularChangeset({
@@ -2374,7 +1998,6 @@ export function updateRefreshers(
2374
1998
  nodeToParent,
2375
1999
  nodeAliases,
2376
2000
  crossFieldKeys,
2377
- rootNodes,
2378
2001
  maxId: maxId as number,
2379
2002
  revisions,
2380
2003
  constraintViolationCount,
@@ -2397,42 +2020,18 @@ export function intoDelta(
2397
2020
  ): DeltaRoot {
2398
2021
  const change = taggedChange.change;
2399
2022
  const rootDelta: Mutable<DeltaRoot> = {};
2023
+ const global: DeltaDetachedNodeChanges[] = [];
2024
+ const rename: DeltaDetachedNodeRename[] = [];
2400
2025
 
2401
2026
  if (!hasConflicts(change)) {
2402
2027
  // If there are no constraint violations, then tree changes apply.
2403
2028
  const fieldDeltas = intoDeltaImpl(
2404
2029
  change.fieldChanges,
2405
2030
  change.nodeChanges,
2406
- change.nodeAliases,
2407
2031
  fieldKinds,
2032
+ global,
2033
+ rename,
2408
2034
  );
2409
-
2410
- const global: DeltaDetachedNodeChanges[] = [];
2411
- for (const [[major, minor], nodeId] of change.rootNodes.nodeChanges.entries()) {
2412
- global.push({
2413
- id: { major, minor },
2414
- fields: deltaFromNodeChange(
2415
- nodeChangeFromId(change.nodeChanges, change.nodeAliases, nodeId),
2416
- change.nodeChanges,
2417
- change.nodeAliases,
2418
- fieldKinds,
2419
- ),
2420
- });
2421
- }
2422
-
2423
- const rename: DeltaDetachedNodeRename[] = [];
2424
- for (const {
2425
- start: oldId,
2426
- value: newId,
2427
- length,
2428
- } of change.rootNodes.oldToNewId.entries()) {
2429
- rename.push({
2430
- count: length,
2431
- oldId: makeDetachedNodeId(oldId.revision, oldId.localId),
2432
- newId: makeDetachedNodeId(newId.revision, newId.localId),
2433
- });
2434
- }
2435
-
2436
2035
  if (fieldDeltas.size > 0) {
2437
2036
  rootDelta.fields = fieldDeltas;
2438
2037
  }
@@ -2461,7 +2060,6 @@ export function intoDelta(
2461
2060
  if (change.refreshers && change.refreshers.size > 0) {
2462
2061
  rootDelta.refreshers = copyDetachedNodes(change.refreshers);
2463
2062
  }
2464
-
2465
2063
  return rootDelta;
2466
2064
  }
2467
2065
 
@@ -2487,21 +2085,32 @@ function copyDetachedNodes(
2487
2085
  function intoDeltaImpl(
2488
2086
  change: FieldChangeMap,
2489
2087
  nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
2490
- nodeAliases: ChangeAtomIdBTree<NodeId>,
2491
2088
  fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
2089
+ global: DeltaDetachedNodeChanges[],
2090
+ rename: DeltaDetachedNodeRename[],
2492
2091
  ): Map<FieldKey, DeltaFieldChanges> {
2493
2092
  const delta: Map<FieldKey, DeltaFieldChanges> = new Map();
2494
2093
 
2495
2094
  for (const [field, fieldChange] of change) {
2496
- const fieldDelta = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(
2095
+ const {
2096
+ local: fieldChanges,
2097
+ global: fieldGlobal,
2098
+ rename: fieldRename,
2099
+ } = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(
2497
2100
  fieldChange.change,
2498
2101
  (childChange): DeltaFieldMap => {
2499
- const nodeChange = nodeChangeFromId(nodeChanges, nodeAliases, childChange);
2500
- return deltaFromNodeChange(nodeChange, nodeChanges, nodeAliases, fieldKinds);
2102
+ const nodeChange = nodeChangeFromId(nodeChanges, childChange);
2103
+ return deltaFromNodeChange(nodeChange, nodeChanges, fieldKinds, global, rename);
2501
2104
  },
2502
2105
  );
2503
- if (fieldDelta !== undefined && fieldDelta.length > 0) {
2504
- delta.set(field, fieldDelta);
2106
+ if (fieldChanges !== undefined && fieldChanges.length > 0) {
2107
+ delta.set(field, fieldChanges);
2108
+ }
2109
+ for (const c of fieldGlobal ?? []) {
2110
+ global.push(c);
2111
+ }
2112
+ for (const r of fieldRename ?? []) {
2113
+ rename.push(r);
2505
2114
  }
2506
2115
  }
2507
2116
  return delta;
@@ -2510,11 +2119,12 @@ function intoDeltaImpl(
2510
2119
  function deltaFromNodeChange(
2511
2120
  change: NodeChangeset,
2512
2121
  nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
2513
- nodeAliases: ChangeAtomIdBTree<NodeId>,
2514
2122
  fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
2123
+ global: DeltaDetachedNodeChanges[],
2124
+ rename: DeltaDetachedNodeRename[],
2515
2125
  ): DeltaFieldMap {
2516
2126
  if (change.fieldChanges !== undefined) {
2517
- return intoDeltaImpl(change.fieldChanges, nodeChanges, nodeAliases, fieldKinds);
2127
+ return intoDeltaImpl(change.fieldChanges, nodeChanges, fieldKinds, global, rename);
2518
2128
  }
2519
2129
  // TODO: update the API to allow undefined to be returned here
2520
2130
  return new Map();
@@ -2579,21 +2189,19 @@ export function getChangeHandler(
2579
2189
  return getFieldKind(fieldKinds, kind).changeHandler;
2580
2190
  }
2581
2191
 
2582
- interface InvertTable {
2583
- change: ModularChangeset;
2192
+ // TODO: TFieldData could instead just be a numeric ID generated by the CrossFieldTable
2193
+ // The CrossFieldTable could have a generic field ID to context table
2194
+ interface CrossFieldTable<TFieldData> {
2195
+ srcTable: CrossFieldMap<unknown>;
2196
+ dstTable: CrossFieldMap<unknown>;
2197
+ srcDependents: CrossFieldMap<TFieldData>;
2198
+ dstDependents: CrossFieldMap<TFieldData>;
2199
+ invalidatedFields: Set<TFieldData>;
2200
+ }
2584
2201
 
2585
- // Entries are keyed on attach ID
2586
- entries: CrossFieldMap<NodeId>;
2202
+ interface InvertTable extends CrossFieldTable<FieldChange> {
2587
2203
  originalFieldToContext: Map<FieldChange, InvertContext>;
2588
- invertedNodeToParent: ChangeAtomIdBTree<NodeLocation>;
2589
- invertRevision: RevisionTag;
2590
- invalidatedFields: Set<FieldChange>;
2591
- invertedRoots: RootNodeTable;
2592
-
2593
- /**
2594
- * Maps from attach ID in the inverted changeset to the corresponding detach ID in the base changeset.
2595
- */
2596
- attachToDetachId: ChangeAtomIdRangeMap<ChangeAtomId>;
2204
+ invertedNodeToParent: ChangeAtomIdBTree<FieldId>;
2597
2205
  }
2598
2206
 
2599
2207
  interface InvertContext {
@@ -2601,11 +2209,7 @@ interface InvertContext {
2601
2209
  invertedField: FieldChange;
2602
2210
  }
2603
2211
 
2604
- interface RebaseTable {
2605
- readonly rebaseVersion: RebaseVersion;
2606
-
2607
- // Entries are keyed on attach ID
2608
- readonly entries: CrossFieldMap<RebaseDetachedNodeEntry>;
2212
+ interface RebaseTable extends CrossFieldTable<FieldChange> {
2609
2213
  readonly baseChange: ModularChangeset;
2610
2214
  readonly newChange: ModularChangeset;
2611
2215
 
@@ -2614,13 +2218,10 @@ interface RebaseTable {
2614
2218
  * to the context for the field.
2615
2219
  */
2616
2220
  readonly baseFieldToContext: Map<FieldChange, RebaseFieldContext>;
2617
- readonly baseRoots: RootNodeTable;
2618
2221
  readonly baseToRebasedNodeId: ChangeAtomIdBTree<NodeId>;
2619
2222
  readonly rebasedFields: Set<FieldChange>;
2620
- readonly rebasedNodeToParent: ChangeAtomIdBTree<NodeLocation>;
2621
- readonly rebasedDetachLocations: ChangeAtomIdRangeMap<FieldId>;
2622
- readonly movedDetaches: ChangeAtomIdRangeMap<boolean>;
2623
- readonly rebasedRootNodes: RootNodeTable;
2223
+ readonly rebasedNodeToParent: ChangeAtomIdBTree<FieldId>;
2224
+ readonly rebasedCrossFieldKeys: CrossFieldKeyTable;
2624
2225
 
2625
2226
  /**
2626
2227
  * List of unprocessed (newId, baseId) pairs encountered so far.
@@ -2634,7 +2235,7 @@ interface RebaseTable {
2634
2235
  readonly fieldsWithUnattachedChild: Set<FieldChange>;
2635
2236
  }
2636
2237
 
2637
- export type FieldIdKey = [RevisionTag | undefined, ChangesetLocalId | undefined, FieldKey];
2238
+ type FieldIdKey = [RevisionTag | undefined, ChangesetLocalId | undefined, FieldKey];
2638
2239
 
2639
2240
  interface RebaseFieldContext {
2640
2241
  baseChange: FieldChange;
@@ -2646,43 +2247,32 @@ interface RebaseFieldContext {
2646
2247
  * The set of node IDs in the base changeset which should be included in the rebased field,
2647
2248
  * even if there is no corresponding node changeset in the new change.
2648
2249
  */
2649
- baseNodeIds: ChangeAtomIdBTree<boolean>;
2250
+ baseNodeIds: NodeId[];
2650
2251
  }
2651
2252
 
2652
2253
  function newComposeTable(
2653
2254
  baseChange: ModularChangeset,
2654
2255
  newChange: ModularChangeset,
2655
- composedRootNodes: RootNodeTable,
2656
- movedCrossFieldKeys: CrossFieldKeyTable,
2657
- removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
2658
- pendingCompositions: PendingCompositions,
2256
+ composedNodeToParent: ChangeAtomIdBTree<FieldId>,
2659
2257
  ): ComposeTable {
2660
2258
  return {
2661
- rebaseVersion: Math.max(
2662
- baseChange.rebaseVersion,
2663
- newChange.rebaseVersion,
2664
- ) as RebaseVersion,
2665
- entries: newDetachedEntryMap(),
2259
+ ...newCrossFieldTable<FieldChange>(),
2666
2260
  baseChange,
2667
2261
  newChange,
2668
2262
  fieldToContext: new Map(),
2669
2263
  newFieldToBaseField: new Map(),
2670
2264
  newToBaseNodeId: newTupleBTree(),
2671
2265
  composedNodes: new Set(),
2672
- movedNodeToParent: newTupleBTree(),
2673
- composedRootNodes,
2674
- movedCrossFieldKeys,
2675
- removedCrossFieldKeys,
2676
- renamesToDelete: newChangeAtomIdRangeMap(),
2677
- pendingCompositions,
2266
+ composedNodeToParent,
2267
+ pendingCompositions: {
2268
+ nodeIdsToCompose: [],
2269
+ affectedBaseFields: newTupleBTree(),
2270
+ affectedNewFields: newTupleBTree(),
2271
+ },
2678
2272
  };
2679
2273
  }
2680
2274
 
2681
- interface ComposeTable {
2682
- readonly rebaseVersion: RebaseVersion;
2683
-
2684
- // Entries are keyed on detach ID
2685
- readonly entries: ChangeAtomIdRangeMap<DetachedNodeEntry>;
2275
+ interface ComposeTable extends CrossFieldTable<FieldChange> {
2686
2276
  readonly baseChange: ModularChangeset;
2687
2277
  readonly newChange: ModularChangeset;
2688
2278
 
@@ -2693,11 +2283,7 @@ interface ComposeTable {
2693
2283
  readonly newFieldToBaseField: Map<FieldChange, FieldChange>;
2694
2284
  readonly newToBaseNodeId: ChangeAtomIdBTree<NodeId>;
2695
2285
  readonly composedNodes: Set<NodeChangeset>;
2696
- readonly movedNodeToParent: ChangeAtomIdBTree<NodeLocation>;
2697
- readonly composedRootNodes: RootNodeTable;
2698
- readonly movedCrossFieldKeys: CrossFieldKeyTable;
2699
- readonly removedCrossFieldKeys: CrossFieldRangeTable<boolean>;
2700
- readonly renamesToDelete: ChangeAtomIdRangeMap<boolean>;
2286
+ readonly composedNodeToParent: ChangeAtomIdBTree<FieldId>;
2701
2287
  readonly pendingCompositions: PendingCompositions;
2702
2288
  }
2703
2289
 
@@ -2712,6 +2298,11 @@ interface PendingCompositions {
2712
2298
  * The set of fields in the base changeset which have been affected by a cross field effect.
2713
2299
  */
2714
2300
  readonly affectedBaseFields: BTree<FieldIdKey, true>;
2301
+
2302
+ /**
2303
+ * The set of fields in the new changeset which have been affected by a cross field effect.
2304
+ */
2305
+ readonly affectedNewFields: BTree<FieldIdKey, true>;
2715
2306
  }
2716
2307
 
2717
2308
  interface ComposeFieldContext {
@@ -2724,6 +2315,16 @@ interface ComposeFieldContext {
2724
2315
  composedChange: FieldChange;
2725
2316
  }
2726
2317
 
2318
+ function newCrossFieldTable<T>(): CrossFieldTable<T> {
2319
+ return {
2320
+ srcTable: newChangeAtomIdRangeMap(),
2321
+ dstTable: newChangeAtomIdRangeMap(),
2322
+ srcDependents: newChangeAtomIdRangeMap(),
2323
+ dstDependents: newChangeAtomIdRangeMap(),
2324
+ invalidatedFields: new Set(),
2325
+ };
2326
+ }
2327
+
2727
2328
  interface ConstraintState {
2728
2329
  violationCount: number;
2729
2330
  }
@@ -2734,696 +2335,282 @@ function newConstraintState(violationCount: number): ConstraintState {
2734
2335
  };
2735
2336
  }
2736
2337
 
2737
- class InvertNodeManagerI implements InvertNodeManager {
2338
+ abstract class CrossFieldManagerI<T> implements CrossFieldManager {
2738
2339
  public constructor(
2739
- private readonly table: InvertTable,
2740
- private readonly fieldId: FieldId,
2340
+ protected readonly crossFieldTable: CrossFieldTable<T>,
2341
+ private readonly currentFieldKey: T,
2342
+ protected readonly allowInval = true,
2741
2343
  ) {}
2742
2344
 
2743
- public invertDetach(
2744
- detachId: ChangeAtomId,
2345
+ public set(
2346
+ target: CrossFieldTarget,
2347
+ revision: RevisionTag | undefined,
2348
+ id: ChangesetLocalId,
2745
2349
  count: number,
2746
- nodeChange: NodeId | undefined,
2747
- newAttachId: ChangeAtomId,
2350
+ newValue: unknown,
2351
+ invalidateDependents: boolean,
2748
2352
  ): void {
2749
- if (nodeChange !== undefined) {
2750
- assert(count === 1, "A node change should only affect one node");
2751
-
2752
- const attachEntry = firstAttachIdFromDetachId(
2753
- this.table.change.rootNodes,
2754
- detachId,
2755
- count,
2756
- );
2757
-
2758
- const attachFieldEntry = this.table.change.crossFieldKeys.getFirst(
2759
- { target: CrossFieldTarget.Destination, ...attachEntry.value },
2760
- count,
2761
- );
2762
-
2763
- if (attachFieldEntry.value === undefined) {
2764
- assignRootChange(
2765
- this.table.invertedRoots,
2766
- this.table.invertedNodeToParent,
2767
- attachEntry.value,
2768
- nodeChange,
2769
- this.fieldId,
2770
- this.table.change.rebaseVersion,
2771
- );
2772
- } else {
2773
- setInCrossFieldMap(this.table.entries, attachEntry.value, count, nodeChange);
2774
- this.table.invalidatedFields.add(
2775
- fieldChangeFromId(this.table.change, attachFieldEntry.value),
2353
+ if (invalidateDependents && this.allowInval) {
2354
+ const lastChangedId = (id as number) + count - 1;
2355
+ let firstId = id;
2356
+ while (firstId <= lastChangedId) {
2357
+ const dependentEntry = getFirstFromCrossFieldMap(
2358
+ this.getDependents(target),
2359
+ revision,
2360
+ firstId,
2361
+ lastChangedId - firstId + 1,
2776
2362
  );
2363
+ if (dependentEntry.value !== undefined) {
2364
+ this.crossFieldTable.invalidatedFields.add(dependentEntry.value);
2365
+ }
2366
+
2367
+ firstId = brand(firstId + dependentEntry.length);
2777
2368
  }
2778
2369
  }
2370
+ setInCrossFieldMap(this.getMap(target), revision, id, count, newValue);
2371
+ }
2779
2372
 
2780
- if (!areEqualChangeAtomIds(detachId, newAttachId)) {
2781
- for (const entry of doesChangeAttachNodes(
2782
- this.table.change.crossFieldKeys,
2783
- detachId,
2373
+ public get(
2374
+ target: CrossFieldTarget,
2375
+ revision: RevisionTag | undefined,
2376
+ id: ChangesetLocalId,
2377
+ count: number,
2378
+ addDependency: boolean,
2379
+ ): RangeQueryResult<ChangeAtomId, unknown> {
2380
+ if (addDependency) {
2381
+ // We assume that if there is already an entry for this ID it is because
2382
+ // a field handler has called compose on the same node multiple times.
2383
+ // In this case we only want to update the latest version, so we overwrite the dependency.
2384
+ setInCrossFieldMap(
2385
+ this.getDependents(target),
2386
+ revision,
2387
+ id,
2784
2388
  count,
2785
- )) {
2786
- if (!entry.value) {
2787
- this.table.attachToDetachId.set(newAttachId, count, detachId);
2788
- this.table.invertedRoots.detachLocations.set(detachId, count, this.fieldId);
2789
- }
2790
- }
2389
+ this.currentFieldKey,
2390
+ );
2791
2391
  }
2392
+ return getFirstFromCrossFieldMap(this.getMap(target), revision, id, count);
2792
2393
  }
2793
2394
 
2794
- public invertAttach(
2795
- attachId: ChangeAtomId,
2395
+ public abstract onMoveIn(id: NodeId): void;
2396
+
2397
+ public abstract moveKey(
2398
+ target: CrossFieldTarget,
2399
+ revision: RevisionTag | undefined,
2400
+ id: ChangesetLocalId,
2796
2401
  count: number,
2797
- ): RangeQueryResult<DetachedNodeEntry> {
2798
- let countToProcess = count;
2402
+ ): void;
2799
2403
 
2800
- const detachIdEntry = firstDetachIdFromAttachId(
2801
- this.table.change.rootNodes,
2802
- attachId,
2803
- countToProcess,
2804
- );
2404
+ private getMap(target: CrossFieldTarget): CrossFieldMap<unknown> {
2405
+ return target === CrossFieldTarget.Source
2406
+ ? this.crossFieldTable.srcTable
2407
+ : this.crossFieldTable.dstTable;
2408
+ }
2805
2409
 
2806
- countToProcess = detachIdEntry.length;
2410
+ private getDependents(target: CrossFieldTarget): CrossFieldMap<T> {
2411
+ return target === CrossFieldTarget.Source
2412
+ ? this.crossFieldTable.srcDependents
2413
+ : this.crossFieldTable.dstDependents;
2414
+ }
2415
+ }
2807
2416
 
2808
- const detachEntry = getFirstFieldForCrossFieldKey(
2809
- this.table.change,
2810
- { target: CrossFieldTarget.Source, ...detachIdEntry.value },
2811
- countToProcess,
2812
- );
2813
- countToProcess = detachEntry.length;
2814
-
2815
- let result: RangeQueryResult<DetachedNodeEntry>;
2816
- if (detachEntry.value === undefined) {
2817
- // This node is detached in the input context of the original change.
2818
- const nodeIdEntry = rangeQueryChangeAtomIdMap(
2819
- this.table.change.rootNodes.nodeChanges,
2820
- detachIdEntry.value,
2821
- countToProcess,
2822
- );
2417
+ class InvertManager extends CrossFieldManagerI<FieldChange> {
2418
+ public constructor(
2419
+ table: InvertTable,
2420
+ field: FieldChange,
2421
+ private readonly fieldId: FieldId,
2422
+ allowInval = true,
2423
+ ) {
2424
+ super(table, field, allowInval);
2425
+ }
2823
2426
 
2824
- countToProcess = nodeIdEntry.length;
2825
- result = {
2826
- value: { nodeChange: nodeIdEntry.value, detachId: detachIdEntry.value },
2827
- length: countToProcess,
2828
- };
2829
- } else {
2830
- const moveEntry = this.table.entries.getFirst(attachId, countToProcess);
2831
- result = { ...moveEntry, value: { nodeChange: moveEntry.value } };
2832
- }
2427
+ public override onMoveIn(id: ChangeAtomId): void {
2428
+ setInChangeAtomIdMap(this.table.invertedNodeToParent, id, this.fieldId);
2429
+ }
2833
2430
 
2834
- if (result.value?.nodeChange !== undefined) {
2835
- setInChangeAtomIdMap(this.table.invertedNodeToParent, result.value.nodeChange, {
2836
- field: this.fieldId,
2837
- });
2838
- }
2839
- return result;
2431
+ public override moveKey(
2432
+ target: CrossFieldTarget,
2433
+ revision: RevisionTag | undefined,
2434
+ id: ChangesetLocalId,
2435
+ count: number,
2436
+ ): void {
2437
+ assert(false, 0x9c5 /* Keys should not be moved manually during invert */);
2438
+ }
2439
+
2440
+ private get table(): InvertTable {
2441
+ return this.crossFieldTable as InvertTable;
2840
2442
  }
2841
2443
  }
2842
2444
 
2843
- class RebaseNodeManagerI implements RebaseNodeManager {
2445
+ class RebaseManager extends CrossFieldManagerI<FieldChange> {
2844
2446
  public constructor(
2845
- private readonly table: RebaseTable,
2447
+ table: RebaseTable,
2448
+ currentField: FieldChange,
2846
2449
  private readonly fieldId: FieldId,
2847
- private readonly allowInval: boolean = true,
2848
- ) {}
2450
+ allowInval = true,
2451
+ ) {
2452
+ super(table, currentField, allowInval);
2453
+ }
2849
2454
 
2850
- public getNewChangesForBaseAttach(
2851
- baseAttachId: ChangeAtomId,
2455
+ public override set(
2456
+ target: CrossFieldTarget,
2457
+ revision: RevisionTag | undefined,
2458
+ id: ChangesetLocalId,
2852
2459
  count: number,
2853
- ): RangeQueryResult<RebaseDetachedNodeEntry | undefined> {
2854
- let countToProcess = count;
2460
+ newValue: unknown,
2461
+ invalidateDependents: boolean,
2462
+ ): void {
2463
+ if (invalidateDependents && this.allowInval) {
2464
+ const newFieldIds = getFieldsForCrossFieldKey(
2465
+ this.table.newChange,
2466
+ {
2467
+ target,
2468
+ revision,
2469
+ localId: id,
2470
+ },
2471
+ count,
2472
+ );
2855
2473
 
2856
- const detachEntry = firstDetachIdFromAttachId(
2857
- this.table.baseChange.rootNodes,
2858
- baseAttachId,
2859
- countToProcess,
2860
- );
2474
+ assert(
2475
+ newFieldIds.length === 0,
2476
+ 0x9c6 /* TODO: Modifying a cross-field key from the new changeset is currently unsupported */,
2477
+ );
2861
2478
 
2862
- countToProcess = detachEntry.length;
2479
+ const baseFieldIds = getFieldsForCrossFieldKey(
2480
+ this.table.baseChange,
2481
+ {
2482
+ target,
2483
+ revision,
2484
+ localId: id,
2485
+ },
2486
+ count,
2487
+ );
2863
2488
 
2864
- const nodeEntry = rangeQueryChangeAtomIdMap(
2865
- this.table.newChange.rootNodes.nodeChanges,
2866
- detachEntry.value,
2867
- countToProcess,
2868
- );
2489
+ assert(
2490
+ baseFieldIds.length > 0,
2491
+ 0x9c7 /* Cross field key not registered in base or new change */,
2492
+ );
2869
2493
 
2870
- countToProcess = nodeEntry.length;
2871
- const newNodeId = nodeEntry.value;
2494
+ for (const baseFieldId of baseFieldIds) {
2495
+ this.table.affectedBaseFields.set(
2496
+ [baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field],
2497
+ true,
2498
+ );
2499
+ }
2500
+ }
2872
2501
 
2873
- const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(
2874
- detachEntry.value,
2875
- countToProcess,
2876
- );
2502
+ super.set(target, revision, id, count, newValue, invalidateDependents);
2503
+ }
2877
2504
 
2878
- countToProcess = newRenameEntry.length;
2505
+ public override onMoveIn(id: ChangeAtomId): void {
2506
+ setInChangeAtomIdMap(this.table.rebasedNodeToParent, id, this.fieldId);
2507
+ }
2879
2508
 
2880
- let result: RangeQueryResult<DetachedNodeEntry | undefined>;
2881
- // eslint-disable-next-line unicorn/prefer-ternary
2882
- if (newNodeId !== undefined || newRenameEntry.value !== undefined) {
2883
- result = {
2884
- ...newRenameEntry,
2885
- value: { detachId: newRenameEntry.value, nodeChange: newNodeId },
2886
- };
2887
- } else {
2888
- // This handles the case where the base changeset has moved these nodes,
2889
- // meaning they were attached in the input context of the base changeset.
2890
- result = this.table.entries.getFirst(baseAttachId, countToProcess);
2891
- }
2892
-
2893
- // TODO: Consider moving these two checks into a separate method so that this function has no side effects.
2894
- if (result.value?.detachId !== undefined) {
2895
- this.table.rebasedDetachLocations.set(
2896
- result.value.detachId,
2897
- result.length,
2898
- this.fieldId,
2899
- );
2900
- }
2901
-
2902
- if (result.value?.nodeChange !== undefined) {
2903
- setInChangeAtomIdMap(this.table.rebasedNodeToParent, result.value.nodeChange, {
2904
- field: this.fieldId,
2905
- });
2906
- }
2907
-
2908
- return result;
2909
- }
2910
-
2911
- public rebaseOverDetach(
2912
- baseDetachId: ChangeAtomId,
2509
+ public override moveKey(
2510
+ target: CrossFieldTarget,
2511
+ revision: RevisionTag | undefined,
2512
+ id: ChangesetLocalId,
2913
2513
  count: number,
2914
- newDetachId: ChangeAtomId | undefined,
2915
- nodeChange: NodeId | undefined,
2916
- cellRename?: ChangeAtomId,
2917
2514
  ): void {
2918
- let countToProcess = count;
2919
- const attachIdEntry = firstAttachIdFromDetachId(
2920
- this.table.baseRoots,
2921
- baseDetachId,
2922
- countToProcess,
2923
- );
2924
- const baseAttachId = attachIdEntry.value;
2925
- countToProcess = attachIdEntry.length;
2926
-
2927
- const attachFieldEntry = getFirstFieldForCrossFieldKey(
2928
- this.table.baseChange,
2929
- { ...baseAttachId, target: CrossFieldTarget.Destination },
2930
- countToProcess,
2931
- );
2932
- countToProcess = attachFieldEntry.length;
2933
-
2934
- const detachedMoveEntry = this.table.baseChange.rootNodes.outputDetachLocations.getFirst(
2935
- baseDetachId,
2936
- countToProcess,
2937
- );
2938
- countToProcess = detachedMoveEntry.length;
2939
-
2940
- const destinationField = attachFieldEntry.value ?? detachedMoveEntry.value;
2941
- if (destinationField !== undefined) {
2942
- // The base detach is part of a move (or move of detach location) in the base changeset.
2943
- setInCrossFieldMap(this.table.entries, baseAttachId, countToProcess, {
2944
- nodeChange,
2945
- detachId: newDetachId,
2946
- cellRename,
2947
- });
2948
-
2949
- if (nodeChange !== undefined || newDetachId !== undefined) {
2950
- this.invalidateBaseFields([destinationField]);
2951
- }
2952
- }
2953
-
2954
- if (attachFieldEntry.value === undefined) {
2955
- // These nodes are detached in the output context of the base changeset.
2956
- if (nodeChange !== undefined) {
2957
- assignRootChange(
2958
- this.table.rebasedRootNodes,
2959
- this.table.rebasedNodeToParent,
2960
- baseAttachId,
2961
- nodeChange,
2962
- this.fieldId,
2963
- this.table.rebaseVersion,
2964
- );
2965
- }
2966
-
2967
- if (newDetachId !== undefined) {
2968
- addNodeRename(
2969
- this.table.rebasedRootNodes,
2970
- baseAttachId,
2971
- newDetachId,
2972
- countToProcess,
2973
- this.fieldId,
2974
- );
2975
- }
2976
- }
2977
-
2978
- if (newDetachId !== undefined) {
2979
- this.table.movedDetaches.set(newDetachId, countToProcess, true);
2980
- }
2981
-
2982
- if (countToProcess < count) {
2983
- const remainingCount = count - countToProcess;
2984
-
2985
- const nextDetachId =
2986
- newDetachId === undefined
2987
- ? undefined
2988
- : offsetChangeAtomId(newDetachId, countToProcess);
2989
-
2990
- this.rebaseOverDetach(
2991
- offsetChangeAtomId(baseDetachId, countToProcess),
2992
- remainingCount,
2993
- nextDetachId,
2994
- nodeChange,
2995
- );
2996
- }
2997
- }
2998
-
2999
- public addDetach(id: ChangeAtomId, count: number): void {
3000
- this.table.rebasedDetachLocations.set(id, count, this.fieldId);
3001
- }
3002
-
3003
- public removeDetach(id: ChangeAtomId, count: number): void {
3004
- this.table.movedDetaches.set(id, count, true);
3005
- }
3006
-
3007
- public doesBaseAttachNodes(
3008
- id: ChangeAtomId,
3009
- count: number,
3010
- ): RangeQueryEntry<ChangeAtomId, boolean> {
3011
- let countToProcess = count;
3012
- const attachEntry = getFirstAttachField(
3013
- this.table.baseChange.crossFieldKeys,
3014
- id,
3015
- countToProcess,
3016
- );
3017
-
3018
- countToProcess = attachEntry.length;
3019
- return { start: id, value: attachEntry.value !== undefined, length: countToProcess };
3020
- }
3021
-
3022
- public getBaseRename(
3023
- id: ChangeAtomId,
3024
- count: number,
3025
- ): RangeQueryResult<ChangeAtomId | undefined> {
3026
- return this.table.baseChange.rootNodes.oldToNewId.getFirst(id, count);
3027
- }
3028
-
3029
- public getNewRenameForBaseRename(
3030
- baseRenameTo: ChangeAtomId,
3031
- count: number,
3032
- ): RangeQueryResult<ChangeAtomId | undefined> {
3033
- let countToProcess = count;
3034
- const inputEntry = firstDetachIdFromAttachId(
3035
- this.table.baseChange.rootNodes,
3036
- baseRenameTo,
3037
- countToProcess,
3038
- );
3039
-
3040
- const attachEntry = getFirstAttachField(
3041
- this.table.baseChange.crossFieldKeys,
3042
- baseRenameTo,
3043
- countToProcess,
2515
+ this.table.rebasedCrossFieldKeys.set(
2516
+ { target, revision, localId: id },
2517
+ count,
2518
+ this.fieldId,
3044
2519
  );
3045
-
3046
- countToProcess = attachEntry.length;
3047
- if (attachEntry.value !== undefined) {
3048
- // These nodes are attached in the output context of the base changeset.
3049
- return { value: undefined, length: countToProcess };
3050
- }
3051
-
3052
- countToProcess = inputEntry.length;
3053
- const inputId = inputEntry.value;
3054
-
3055
- const moveEntry = this.table.entries.getFirst(inputId, countToProcess);
3056
-
3057
- countToProcess = moveEntry.length;
3058
- if (moveEntry.value !== undefined) {
3059
- return { ...moveEntry, value: moveEntry.value.cellRename ?? moveEntry.value.detachId };
3060
- }
3061
-
3062
- return this.table.newChange.rootNodes.oldToNewId.getFirst(inputId, countToProcess);
3063
- }
3064
-
3065
- private invalidateBaseFields(fields: FieldId[]): void {
3066
- if (this.allowInval) {
3067
- for (const fieldId of fields) {
3068
- this.table.affectedBaseFields.set(fieldIdKeyFromFieldId(fieldId), true);
3069
- }
3070
- }
3071
2520
  }
3072
- }
3073
-
3074
- function assignRootChange(
3075
- table: RootNodeTable,
3076
- nodeToParent: ChangeAtomIdBTree<NodeLocation> | undefined,
3077
- detachId: ChangeAtomId,
3078
- nodeId: NodeId,
3079
- detachLocation: FieldId | undefined,
3080
- rebaseVersion: RebaseVersion,
3081
- ): void {
3082
- assert(
3083
- rebaseVersion >= 2 || detachLocation !== undefined,
3084
- "All root changes need a detach location to support compatibility with older client versions",
3085
- );
3086
-
3087
- setInChangeAtomIdMap(table.nodeChanges, detachId, nodeId);
3088
2521
 
3089
- if (nodeToParent !== undefined) {
3090
- setInChangeAtomIdMap(nodeToParent, nodeId, { root: detachId });
2522
+ private get table(): RebaseTable {
2523
+ return this.crossFieldTable as RebaseTable;
3091
2524
  }
3092
-
3093
- table.detachLocations.set(detachId, 1, detachLocation);
3094
2525
  }
3095
2526
 
3096
- class ComposeNodeManagerI implements ComposeNodeManager {
2527
+ // TODO: Deduplicate this with RebaseTable
2528
+ class ComposeManager extends CrossFieldManagerI<FieldChange> {
3097
2529
  public constructor(
3098
- private readonly table: ComposeTable,
2530
+ table: ComposeTable,
2531
+ currentField: FieldChange,
3099
2532
  private readonly fieldId: FieldId,
3100
- private readonly allowInval: boolean = true,
3101
- ) {}
3102
-
3103
- public getNewChangesForBaseDetach(
3104
- baseDetachId: ChangeAtomId,
3105
- count: number,
3106
- ): RangeQueryResult<DetachedNodeEntry | undefined> {
3107
- let countToProcess = count;
3108
-
3109
- const baseAttachEntry = getFirstFieldForCrossFieldKey(
3110
- this.table.baseChange,
3111
- { target: CrossFieldTarget.Destination, ...baseDetachId },
3112
- countToProcess,
3113
- );
3114
-
3115
- countToProcess = baseAttachEntry.length;
3116
-
3117
- let result: RangeQueryResult<DetachedNodeEntry | undefined>;
3118
- if (baseAttachEntry.value === undefined) {
3119
- // The detached nodes are still detached in the new change's input context.
3120
- const rootEntry = rangeQueryChangeAtomIdMap(
3121
- this.table.newChange.rootNodes.nodeChanges,
3122
- baseDetachId,
3123
- countToProcess,
3124
- );
3125
-
3126
- countToProcess = rootEntry.length;
3127
-
3128
- const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(
3129
- baseDetachId,
3130
- countToProcess,
3131
- );
3132
-
3133
- countToProcess = newRenameEntry.length;
3134
-
3135
- result = {
3136
- value: { nodeChange: rootEntry.value, detachId: newRenameEntry.value },
3137
- length: countToProcess,
3138
- };
3139
- } else {
3140
- // The base detach was part of a move.
3141
- // We check if we've previously seen a node change at the move destination.
3142
- const entry = this.table.entries.getFirst(baseDetachId, countToProcess);
3143
- result = { value: entry.value, length: entry.length };
3144
- }
3145
-
3146
- // TODO: Consider moving this to a separate method so that this method can be side-effect free.
3147
- if (result.value?.nodeChange !== undefined) {
3148
- setInChangeAtomIdMap(this.table.movedNodeToParent, result.value.nodeChange, {
3149
- field: this.fieldId,
3150
- });
3151
- }
3152
-
3153
- return result;
2533
+ allowInval = true,
2534
+ ) {
2535
+ super(table, currentField, allowInval);
3154
2536
  }
3155
2537
 
3156
- public composeAttachDetach(
3157
- baseAttachId: ChangeAtomId,
3158
- newDetachId: ChangeAtomId,
2538
+ public override set(
2539
+ target: CrossFieldTarget,
2540
+ revision: RevisionTag | undefined,
2541
+ id: ChangesetLocalId,
3159
2542
  count: number,
2543
+ newValue: unknown,
2544
+ invalidateDependents: boolean,
3160
2545
  ): void {
3161
- let countToProcess = count;
3162
-
3163
- const newAttachEntry = getFirstAttachField(
3164
- this.table.newChange.crossFieldKeys,
3165
- newDetachId,
3166
- countToProcess,
3167
- );
3168
-
3169
- countToProcess = newAttachEntry.length;
3170
-
3171
- // Both changes can have the same ID if they came from inverse changesets.
3172
- // If the new detach is part of a move,
3173
- // then both input changesets contain the attach cross-field key for this ID.
3174
- // The new attach may still exist in the composed changeset so we do not remove it here.
3175
- // The new attach will typically cancel with a base detach,
3176
- // in which case the cross-field key will be removed in `composeDetachAttach`.
3177
- const hasNewAttachWithBaseAttachId =
3178
- areEqualChangeAtomIds(baseAttachId, newDetachId) && newAttachEntry.value !== undefined;
3179
-
3180
- if (!hasNewAttachWithBaseAttachId) {
3181
- this.table.removedCrossFieldKeys.set(
3182
- { ...baseAttachId, target: CrossFieldTarget.Destination },
3183
- countToProcess,
3184
- true,
3185
- );
3186
- }
3187
-
3188
- const baseDetachEntry = getFirstDetachField(
3189
- this.table.baseChange.crossFieldKeys,
3190
- baseAttachId,
3191
- countToProcess,
3192
- );
3193
-
3194
- countToProcess = baseDetachEntry.length;
3195
-
3196
- const baseRootIdEntry = firstDetachIdFromAttachId(
3197
- this.table.baseChange.rootNodes,
3198
- baseAttachId,
3199
- countToProcess,
3200
- );
3201
- countToProcess = baseRootIdEntry.length;
3202
-
3203
- const baseDetachId = baseRootIdEntry.value;
3204
-
3205
- if (baseDetachEntry.value === undefined) {
3206
- const baseDetachLocationEntry = this.table.baseChange.rootNodes.detachLocations.getFirst(
3207
- baseDetachId,
3208
- countToProcess,
3209
- );
3210
- countToProcess = baseDetachLocationEntry.length;
3211
-
3212
- // These nodes were detached in the base change's input context,
3213
- // so the net effect of the two changes is a rename.
3214
- appendNodeRename(
3215
- this.table.composedRootNodes,
3216
- baseAttachId,
3217
- newDetachId,
3218
- baseDetachEntry.length,
3219
- this.table.baseChange.rootNodes,
3220
- baseDetachLocationEntry.value ?? this.fieldId,
3221
- );
3222
-
3223
- this.table.removedCrossFieldKeys.set(
3224
- { ...newDetachId, target: CrossFieldTarget.Source },
3225
- countToProcess,
3226
- true,
2546
+ if (invalidateDependents && this.allowInval) {
2547
+ const newFieldIds = getFieldsForCrossFieldKey(
2548
+ this.table.newChange,
2549
+ {
2550
+ target,
2551
+ revision,
2552
+ localId: id,
2553
+ },
2554
+ count,
3227
2555
  );
3228
- } else {
3229
- // The base change moves these nodes.
3230
- const prevEntry =
3231
- this.table.entries.getFirst(baseAttachId, baseDetachEntry.length).value ?? {};
3232
-
3233
- this.table.entries.set(baseAttachId, baseDetachEntry.length, {
3234
- ...prevEntry,
3235
- detachId: newDetachId,
3236
- });
3237
2556
 
3238
- // The new detach will replace the base detach, so we remove the key for the base detach, unless they have the same ID.
3239
- if (!areEqualChangeAtomIds(baseAttachId, newDetachId)) {
3240
- this.table.removedCrossFieldKeys.set(
3241
- { ...baseAttachId, target: CrossFieldTarget.Source },
3242
- countToProcess,
3243
- true,
2557
+ if (newFieldIds.length > 0) {
2558
+ for (const newFieldId of newFieldIds) {
2559
+ this.table.pendingCompositions.affectedNewFields.set(
2560
+ [newFieldId.nodeId?.revision, newFieldId.nodeId?.localId, newFieldId.field],
2561
+ true,
2562
+ );
2563
+ }
2564
+ } else {
2565
+ const baseFieldIds = getFieldsForCrossFieldKey(
2566
+ this.table.baseChange,
2567
+ {
2568
+ target,
2569
+ revision,
2570
+ localId: id,
2571
+ },
2572
+ count,
3244
2573
  );
3245
- }
3246
-
3247
- this.table.movedCrossFieldKeys.set(
3248
- { ...newDetachId, target: CrossFieldTarget.Source },
3249
- countToProcess,
3250
- baseDetachEntry.value,
3251
- );
3252
2574
 
3253
- this.invalidateBaseFields([baseDetachEntry.value]);
3254
- }
3255
-
3256
- if (newAttachEntry.value === undefined) {
3257
- const newOutputDetachLocationEntry =
3258
- this.table.newChange.rootNodes.outputDetachLocations.getFirst(
3259
- newDetachId,
3260
- countToProcess,
2575
+ assert(
2576
+ baseFieldIds.length > 0,
2577
+ 0x9c8 /* Cross field key not registered in base or new change */,
3261
2578
  );
3262
2579
 
3263
- countToProcess = newOutputDetachLocationEntry.length;
3264
-
3265
- this.table.composedRootNodes.outputDetachLocations.set(
3266
- newDetachId,
3267
- countToProcess,
3268
- newOutputDetachLocationEntry.value ?? this.fieldId,
3269
- );
3270
- }
3271
-
3272
- if (countToProcess < count) {
3273
- const remainingCount = count - countToProcess;
3274
- this.composeAttachDetach(
3275
- offsetChangeAtomId(baseAttachId, countToProcess),
3276
- offsetChangeAtomId(newDetachId, countToProcess),
3277
- remainingCount,
3278
- );
3279
- }
3280
- }
3281
-
3282
- public sendNewChangesToBaseSourceLocation(
3283
- baseAttachId: ChangeAtomId,
3284
- newChanges: NodeId,
3285
- ): void {
3286
- const { value: baseDetachId } = firstDetachIdFromAttachId(
3287
- this.table.baseChange.rootNodes,
3288
- baseAttachId,
3289
- 1,
3290
- );
3291
-
3292
- const detachFields = getFieldsForCrossFieldKey(
3293
- this.table.baseChange,
3294
- {
3295
- ...baseDetachId,
3296
- target: CrossFieldTarget.Source,
3297
- },
3298
- 1,
3299
- );
3300
-
3301
- if (detachFields.length > 0) {
3302
- // The base attach is part of a move in the base changeset.
3303
- const prevEntry = this.table.entries.getFirst(baseDetachId, 1).value ?? {};
3304
- this.table.entries.set(baseDetachId, 1, { ...prevEntry, nodeChange: newChanges });
3305
-
3306
- if (newChanges !== undefined) {
3307
- this.invalidateBaseFields(detachFields);
3308
- }
3309
- } else {
3310
- const baseNodeId = getFromChangeAtomIdMap(
3311
- this.table.baseChange.rootNodes.nodeChanges,
3312
- baseDetachId,
3313
- );
3314
-
3315
- if (baseNodeId === undefined) {
3316
- assignRootChange(
3317
- this.table.composedRootNodes,
3318
- this.table.movedNodeToParent,
3319
- baseDetachId,
3320
- newChanges,
3321
- this.fieldId,
3322
- this.table.rebaseVersion,
3323
- );
3324
- } else {
3325
- addNodesToCompose(this.table, baseNodeId, newChanges);
2580
+ for (const baseFieldId of baseFieldIds) {
2581
+ this.table.pendingCompositions.affectedBaseFields.set(
2582
+ [baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field],
2583
+ true,
2584
+ );
2585
+ }
3326
2586
  }
3327
2587
  }
3328
- }
3329
2588
 
3330
- private areSameNodes(
3331
- baseDetachId: ChangeAtomId,
3332
- newAttachId: ChangeAtomId,
3333
- count: number,
3334
- ): RangeQueryResult<boolean> {
3335
- const renamedDetachEntry = firstAttachIdFromDetachId(
3336
- this.table.composedRootNodes,
3337
- baseDetachId,
3338
- count,
3339
- );
2589
+ super.set(target, revision, id, count, newValue, invalidateDependents);
2590
+ }
3340
2591
 
3341
- const isReattachOfSameNodes = areEqualChangeAtomIds(renamedDetachEntry.value, newAttachId);
3342
- return { ...renamedDetachEntry, value: isReattachOfSameNodes };
2592
+ public override onMoveIn(id: ChangeAtomId): void {
2593
+ setInChangeAtomIdMap(this.table.composedNodeToParent, id, this.fieldId);
3343
2594
  }
3344
2595
 
3345
- public composeDetachAttach(
3346
- baseDetachId: ChangeAtomId,
3347
- newAttachId: ChangeAtomId,
2596
+ public override moveKey(
2597
+ target: CrossFieldTarget,
2598
+ revision: RevisionTag | undefined,
2599
+ id: ChangesetLocalId,
3348
2600
  count: number,
3349
- composeToPin: boolean,
3350
2601
  ): void {
3351
- const areSameEntry = this.areSameNodes(baseDetachId, newAttachId, count);
3352
-
3353
- const countToProcess = areSameEntry.length;
3354
- if (areSameEntry.value) {
3355
- // These nodes have been moved back to their original location, so the composed changeset should not have any renames for them.
3356
- // Note that deleting the rename from `this.table.composedRootNodes` would change the result of this method
3357
- // if it were rerun due to the field being invalidated, so we instead record that the rename should be deleted later.
3358
- this.table.renamesToDelete.set(baseDetachId, countToProcess, true);
3359
- }
3360
-
3361
- if (composeToPin) {
3362
- this.table.movedCrossFieldKeys.set(
3363
- { target: CrossFieldTarget.Source, ...newAttachId },
3364
- countToProcess,
3365
- this.fieldId,
3366
- );
3367
-
3368
- if (!areEqualChangeAtomIds(baseDetachId, newAttachId)) {
3369
- // The pin will have `newAttachId` as both its detach and attach ID.
3370
- // So we remove `baseDetachId` unless that is equal to the pin's detach ID.
3371
- this.table.removedCrossFieldKeys.set(
3372
- { target: CrossFieldTarget.Source, ...baseDetachId },
3373
- countToProcess,
3374
- true,
3375
- );
3376
- }
3377
-
3378
- // Note that while change2 should already have this key, change1 may have a rollback for the same ID in a different location.
3379
- // In that case, change1's attach should be canceled out by a detach from change2.
3380
- // Here we make sure that the composed change has the correct location (this field) for the attach ID.
3381
- this.table.movedCrossFieldKeys.set(
3382
- { target: CrossFieldTarget.Destination, ...newAttachId },
3383
- countToProcess,
3384
- this.fieldId,
3385
- );
3386
- } else {
3387
- this.table.removedCrossFieldKeys.set(
3388
- { target: CrossFieldTarget.Source, ...baseDetachId },
3389
- countToProcess,
3390
- true,
3391
- );
3392
-
3393
- this.table.removedCrossFieldKeys.set(
3394
- { target: CrossFieldTarget.Destination, ...newAttachId },
3395
- countToProcess,
3396
- true,
3397
- );
3398
- }
3399
-
3400
- if (countToProcess < count) {
3401
- this.composeAttachDetach(
3402
- offsetChangeAtomId(baseDetachId, countToProcess),
3403
- offsetChangeAtomId(newAttachId, countToProcess),
3404
- count - countToProcess,
3405
- );
3406
- }
2602
+ throw new Error("Moving cross-field keys during compose is currently unsupported");
3407
2603
  }
3408
2604
 
3409
- private invalidateBaseFields(fields: FieldId[]): void {
3410
- if (this.allowInval) {
3411
- for (const fieldId of fields) {
3412
- this.table.pendingCompositions.affectedBaseFields.set(
3413
- fieldIdKeyFromFieldId(fieldId),
3414
- true,
3415
- );
3416
- }
3417
- }
2605
+ private get table(): ComposeTable {
2606
+ return this.crossFieldTable as ComposeTable;
3418
2607
  }
3419
2608
  }
3420
2609
 
3421
2610
  function makeModularChangeset(props?: {
3422
- rebaseVersion?: RebaseVersion;
3423
2611
  fieldChanges?: FieldChangeMap;
3424
2612
  nodeChanges?: ChangeAtomIdBTree<NodeChangeset>;
3425
- rootNodes?: RootNodeTable;
3426
- nodeToParent?: ChangeAtomIdBTree<NodeLocation>;
2613
+ nodeToParent?: ChangeAtomIdBTree<FieldId>;
3427
2614
  nodeAliases?: ChangeAtomIdBTree<NodeId>;
3428
2615
  crossFieldKeys?: CrossFieldKeyTable;
3429
2616
  maxId: number;
@@ -3438,13 +2625,11 @@ function makeModularChangeset(props?: {
3438
2625
  }): ModularChangeset {
3439
2626
  const p = props ?? { maxId: -1 };
3440
2627
  const changeset: Mutable<ModularChangeset> = {
3441
- rebaseVersion: p.rebaseVersion ?? 1,
3442
2628
  fieldChanges: p.fieldChanges ?? new Map(),
3443
2629
  nodeChanges: p.nodeChanges ?? newTupleBTree(),
3444
- rootNodes: p.rootNodes ?? newRootTable(),
3445
2630
  nodeToParent: p.nodeToParent ?? newTupleBTree(),
3446
2631
  nodeAliases: p.nodeAliases ?? newTupleBTree(),
3447
- crossFieldKeys: p.crossFieldKeys ?? newCrossFieldRangeTable(),
2632
+ crossFieldKeys: p.crossFieldKeys ?? newCrossFieldKeyTable(),
3448
2633
  };
3449
2634
 
3450
2635
  if (p.revisions !== undefined && p.revisions.length > 0) {
@@ -3477,7 +2662,6 @@ function makeModularChangeset(props?: {
3477
2662
  if (p.refreshers !== undefined && p.refreshers.size > 0) {
3478
2663
  changeset.refreshers = p.refreshers;
3479
2664
  }
3480
-
3481
2665
  return changeset;
3482
2666
  }
3483
2667
 
@@ -3497,10 +2681,6 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3497
2681
  this.codecOptions = codecOptions;
3498
2682
  }
3499
2683
 
3500
- public isInTransaction(): boolean {
3501
- return this.transactionDepth > 0;
3502
- }
3503
-
3504
2684
  public override enterTransaction(): void {
3505
2685
  this.transactionDepth += 1;
3506
2686
  if (this.transactionDepth === 1) {
@@ -3555,7 +2735,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3555
2735
  * @param revision - the revision of the change
3556
2736
  */
3557
2737
  public submitChange(
3558
- field: NormalizedFieldUpPath,
2738
+ field: FieldUpPath,
3559
2739
  fieldKind: FieldKindIdentifier,
3560
2740
  change: FieldChangeset,
3561
2741
  revision: RevisionTag,
@@ -3569,8 +2749,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3569
2749
  fieldChange: { fieldKind, change },
3570
2750
  nodeChanges: newTupleBTree(),
3571
2751
  nodeToParent: newTupleBTree(),
3572
- crossFieldKeys: newCrossFieldRangeTable(),
3573
- rootNodes: newRootTable(),
2752
+ crossFieldKeys: newCrossFieldKeyTable(),
3574
2753
  idAllocator: this.idAllocator,
3575
2754
  localCrossFieldKeys,
3576
2755
  revision,
@@ -3592,7 +2771,6 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3592
2771
  ? makeModularChangeset({
3593
2772
  maxId: this.idAllocator.getMaxId(),
3594
2773
  builds: change.builds,
3595
- rootNodes: renameTableFromRenameDescriptions(change.renames ?? []),
3596
2774
  revisions: [{ revision: change.revision }],
3597
2775
  })
3598
2776
  : buildModularChangesetFromField({
@@ -3603,8 +2781,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3603
2781
  },
3604
2782
  nodeChanges: newTupleBTree(),
3605
2783
  nodeToParent: newTupleBTree(),
3606
- crossFieldKeys: newCrossFieldRangeTable(),
3607
- rootNodes: newRootTable(),
2784
+ crossFieldKeys: newCrossFieldKeyTable(),
3608
2785
  idAllocator: this.idAllocator,
3609
2786
  localCrossFieldKeys: getChangeHandler(
3610
2787
  this.fieldKinds,
@@ -3631,7 +2808,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3631
2808
  return brand(this.idAllocator.allocate(count));
3632
2809
  }
3633
2810
 
3634
- public addNodeExistsConstraint(path: NormalizedUpPath, revision: RevisionTag): void {
2811
+ public addNodeExistsConstraint(path: UpPath, revision: RevisionTag): void {
3635
2812
  const nodeChange: NodeChangeset = {
3636
2813
  nodeExistsConstraint: { violated: false },
3637
2814
  };
@@ -3643,8 +2820,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3643
2820
  nodeChange,
3644
2821
  nodeChanges: newTupleBTree(),
3645
2822
  nodeToParent: newTupleBTree(),
3646
- crossFieldKeys: newCrossFieldRangeTable(),
3647
- rootNodes: newRootTable(),
2823
+ crossFieldKeys: newCrossFieldKeyTable(),
3648
2824
  idAllocator: this.idAllocator,
3649
2825
  revision,
3650
2826
  }),
@@ -3653,7 +2829,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3653
2829
  );
3654
2830
  }
3655
2831
 
3656
- public addNodeExistsConstraintOnRevert(path: NormalizedUpPath, revision: RevisionTag): void {
2832
+ public addNodeExistsConstraintOnRevert(path: UpPath, revision: RevisionTag): void {
3657
2833
  const nodeChange: NodeChangeset = {
3658
2834
  nodeExistsConstraintOnRevert: { violated: false },
3659
2835
  };
@@ -3665,8 +2841,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3665
2841
  nodeChange,
3666
2842
  nodeChanges: newTupleBTree(),
3667
2843
  nodeToParent: newTupleBTree(),
3668
- crossFieldKeys: newCrossFieldRangeTable(),
3669
- rootNodes: newRootTable(),
2844
+ crossFieldKeys: newCrossFieldKeyTable(),
3670
2845
  idAllocator: this.idAllocator,
3671
2846
  revision,
3672
2847
  }),
@@ -3706,13 +2881,12 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
3706
2881
  }
3707
2882
  }
3708
2883
 
3709
- export function buildModularChangesetFromField(props: {
3710
- path: NormalizedFieldUpPath;
2884
+ function buildModularChangesetFromField(props: {
2885
+ path: FieldUpPath;
3711
2886
  fieldChange: FieldChange;
3712
2887
  nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
3713
- nodeToParent: ChangeAtomIdBTree<NodeLocation>;
2888
+ nodeToParent: ChangeAtomIdBTree<FieldId>;
3714
2889
  crossFieldKeys: CrossFieldKeyTable;
3715
- rootNodes: RootNodeTable;
3716
2890
  localCrossFieldKeys?: CrossFieldKeyRange[];
3717
2891
  revision: RevisionTag;
3718
2892
  idAllocator?: IdAllocator;
@@ -3724,7 +2898,6 @@ export function buildModularChangesetFromField(props: {
3724
2898
  nodeChanges,
3725
2899
  nodeToParent,
3726
2900
  crossFieldKeys,
3727
- rootNodes,
3728
2901
  idAllocator = idAllocatorFromMaxId(),
3729
2902
  localCrossFieldKeys = [],
3730
2903
  childId,
@@ -3733,17 +2906,14 @@ export function buildModularChangesetFromField(props: {
3733
2906
  const fieldChanges: FieldChangeMap = new Map([[path.field, fieldChange]]);
3734
2907
 
3735
2908
  if (path.parent === undefined) {
3736
- const field = { nodeId: undefined, field: path.field };
3737
2909
  for (const { key, count } of localCrossFieldKeys) {
3738
- crossFieldKeys.set(key, count, field);
2910
+ crossFieldKeys.set(key, count, { nodeId: undefined, field: path.field });
3739
2911
  }
3740
2912
 
3741
2913
  if (childId !== undefined) {
3742
2914
  setInChangeAtomIdMap(nodeToParent, childId, {
3743
- field: {
3744
- nodeId: undefined,
3745
- field: path.field,
3746
- },
2915
+ nodeId: undefined,
2916
+ field: path.field,
3747
2917
  });
3748
2918
  }
3749
2919
 
@@ -3752,7 +2922,6 @@ export function buildModularChangesetFromField(props: {
3752
2922
  nodeChanges,
3753
2923
  nodeToParent,
3754
2924
  crossFieldKeys,
3755
- rootNodes,
3756
2925
  maxId: idAllocator.getMaxId(),
3757
2926
  revisions: [{ revision }],
3758
2927
  });
@@ -3763,7 +2932,6 @@ export function buildModularChangesetFromField(props: {
3763
2932
  };
3764
2933
 
3765
2934
  const parentId: NodeId = { localId: brand(idAllocator.allocate()), revision };
3766
- const fieldId = { nodeId: parentId, field: path.field };
3767
2935
 
3768
2936
  for (const { key, count } of localCrossFieldKeys) {
3769
2937
  crossFieldKeys.set(key, count, { nodeId: parentId, field: path.field });
@@ -3771,7 +2939,8 @@ export function buildModularChangesetFromField(props: {
3771
2939
 
3772
2940
  if (childId !== undefined) {
3773
2941
  setInChangeAtomIdMap(nodeToParent, childId, {
3774
- field: fieldId,
2942
+ nodeId: parentId,
2943
+ field: path.field,
3775
2944
  });
3776
2945
  }
3777
2946
 
@@ -3781,7 +2950,6 @@ export function buildModularChangesetFromField(props: {
3781
2950
  nodeChanges,
3782
2951
  nodeToParent,
3783
2952
  crossFieldKeys,
3784
- rootNodes,
3785
2953
  idAllocator,
3786
2954
  revision,
3787
2955
  nodeId: parentId,
@@ -3789,12 +2957,11 @@ export function buildModularChangesetFromField(props: {
3789
2957
  }
3790
2958
 
3791
2959
  function buildModularChangesetFromNode(props: {
3792
- path: NormalizedUpPath;
2960
+ path: UpPath;
3793
2961
  nodeChange: NodeChangeset;
3794
2962
  nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
3795
- nodeToParent: ChangeAtomIdBTree<NodeLocation>;
2963
+ nodeToParent: ChangeAtomIdBTree<FieldId>;
3796
2964
  crossFieldKeys: CrossFieldKeyTable;
3797
- rootNodes: RootNodeTable;
3798
2965
  idAllocator: IdAllocator;
3799
2966
  revision: RevisionTag;
3800
2967
  nodeId?: NodeId;
@@ -3808,43 +2975,27 @@ function buildModularChangesetFromNode(props: {
3808
2975
  nodeId = { localId: brand(idAllocator.allocate()), revision },
3809
2976
  } = props;
3810
2977
  setInChangeAtomIdMap(nodeChanges, nodeId, nodeChange);
2978
+ const fieldChangeset = genericFieldKind.changeHandler.editor.buildChildChanges([
2979
+ [path.parentIndex, nodeId],
2980
+ ]);
3811
2981
 
3812
- if (isDetachedUpPathRoot(path)) {
3813
- props.rootNodes.nodeChanges.set(
3814
- [path.detachedNodeId.major, brand(path.detachedNodeId.minor)],
3815
- nodeId,
3816
- );
3817
- return makeModularChangeset({
3818
- rootNodes: props.rootNodes,
3819
- nodeChanges: props.nodeChanges,
3820
- nodeToParent: props.nodeToParent,
3821
- crossFieldKeys: props.crossFieldKeys,
3822
- maxId: props.idAllocator.getMaxId(),
3823
- revisions: [{ revision: props.revision }],
3824
- });
3825
- } else {
3826
- const fieldChangeset = genericFieldKind.changeHandler.editor.buildChildChanges([
3827
- [path.parentIndex, nodeId],
3828
- ]);
3829
-
3830
- const fieldChange: FieldChange = {
3831
- fieldKind: genericFieldKind.identifier,
3832
- change: fieldChangeset,
3833
- };
2982
+ const fieldChange: FieldChange = {
2983
+ fieldKind: genericFieldKind.identifier,
2984
+ change: fieldChangeset,
2985
+ };
3834
2986
 
3835
- return buildModularChangesetFromField({
3836
- ...props,
3837
- path: { parent: path.parent, field: path.parentField },
3838
- fieldChange,
3839
- localCrossFieldKeys: [],
3840
- childId: nodeId,
3841
- });
3842
- }
2987
+ return buildModularChangesetFromField({
2988
+ ...props,
2989
+ path: { parent: path.parent, field: path.parentField },
2990
+ fieldChange,
2991
+ localCrossFieldKeys: [],
2992
+ childId: nodeId,
2993
+ });
3843
2994
  }
3844
2995
 
3845
2996
  export interface FieldEditDescription {
3846
2997
  type: "field";
3847
- field: NormalizedFieldUpPath;
2998
+ field: FieldUpPath;
3848
2999
  fieldKind: FieldKindIdentifier;
3849
3000
  change: FieldChangeset;
3850
3001
  revision: RevisionTag;
@@ -3854,23 +3005,6 @@ export interface GlobalEditDescription {
3854
3005
  type: "global";
3855
3006
  revision: RevisionTag;
3856
3007
  builds?: ChangeAtomIdBTree<TreeChunk>;
3857
- renames?: RenameDescription[];
3858
- }
3859
-
3860
- export interface RenameDescription {
3861
- count: number;
3862
- oldId: ChangeAtomId;
3863
- newId: ChangeAtomId;
3864
- detachLocation: FieldId | undefined;
3865
- }
3866
-
3867
- function renameTableFromRenameDescriptions(renames: RenameDescription[]): RootNodeTable {
3868
- const table = newRootTable();
3869
- for (const rename of renames) {
3870
- addNodeRename(table, rename.oldId, rename.newId, rename.count, rename.detachLocation);
3871
- }
3872
-
3873
- return table;
3874
3008
  }
3875
3009
 
3876
3010
  export type EditDescription = FieldEditDescription | GlobalEditDescription;
@@ -3894,6 +3028,20 @@ function getRevInfoFromTaggedChanges(changes: TaggedChange<ModularChangeset>[]):
3894
3028
  }
3895
3029
  }
3896
3030
 
3031
+ const rolledBackRevisions: RevisionTag[] = [];
3032
+ for (const info of revInfos) {
3033
+ if (info.rollbackOf !== undefined) {
3034
+ rolledBackRevisions.push(info.rollbackOf);
3035
+ }
3036
+ }
3037
+
3038
+ rolledBackRevisions.reverse();
3039
+ for (const revision of rolledBackRevisions) {
3040
+ if (!revisions.has(revision)) {
3041
+ revInfos.push({ revision });
3042
+ }
3043
+ }
3044
+
3897
3045
  return { maxId: brand(maxId), revInfos };
3898
3046
  }
3899
3047
 
@@ -3913,28 +3061,25 @@ function revisionInfoFromTaggedChange(
3913
3061
  return revInfos;
3914
3062
  }
3915
3063
 
3916
- function fieldChangeFromId(change: ModularChangeset, id: FieldId): FieldChange {
3917
- const fieldId = normalizeFieldId(id, change.nodeAliases);
3918
- const fieldMap = fieldMapFromNodeId(
3919
- change.fieldChanges,
3920
- change.nodeChanges,
3921
- change.nodeAliases,
3922
- fieldId.nodeId,
3923
- );
3064
+ function fieldChangeFromId(
3065
+ fields: FieldChangeMap,
3066
+ nodes: ChangeAtomIdBTree<NodeChangeset>,
3067
+ id: FieldId,
3068
+ ): FieldChange {
3069
+ const fieldMap = fieldMapFromNodeId(fields, nodes, id.nodeId);
3924
3070
  return fieldMap.get(id.field) ?? fail(0xb25 /* No field exists for the given ID */);
3925
3071
  }
3926
3072
 
3927
3073
  function fieldMapFromNodeId(
3928
3074
  rootFieldMap: FieldChangeMap,
3929
3075
  nodes: ChangeAtomIdBTree<NodeChangeset>,
3930
- aliases: ChangeAtomIdBTree<NodeId>,
3931
3076
  nodeId: NodeId | undefined,
3932
3077
  ): FieldChangeMap {
3933
3078
  if (nodeId === undefined) {
3934
3079
  return rootFieldMap;
3935
3080
  }
3936
3081
 
3937
- const node = nodeChangeFromId(nodes, aliases, nodeId);
3082
+ const node = nodeChangeFromId(nodes, nodeId);
3938
3083
  assert(node.fieldChanges !== undefined, 0x9c9 /* Expected node to have field changes */);
3939
3084
  return node.fieldChanges;
3940
3085
  }
@@ -3951,13 +3096,8 @@ function rebasedNodeIdFromBaseNodeId(table: RebaseTable, baseId: NodeId): NodeId
3951
3096
  return getFromChangeAtomIdMap(table.baseToRebasedNodeId, baseId) ?? baseId;
3952
3097
  }
3953
3098
 
3954
- function nodeChangeFromId(
3955
- nodes: ChangeAtomIdBTree<NodeChangeset>,
3956
- aliases: ChangeAtomIdBTree<NodeId>,
3957
- id: NodeId,
3958
- ): NodeChangeset {
3959
- const normalizedId = normalizeNodeId(id, aliases);
3960
- const node = getFromChangeAtomIdMap(nodes, normalizedId);
3099
+ function nodeChangeFromId(nodes: ChangeAtomIdBTree<NodeChangeset>, id: NodeId): NodeChangeset {
3100
+ const node = getFromChangeAtomIdMap(nodes, id);
3961
3101
  assert(node !== undefined, 0x9ca /* Unknown node ID */);
3962
3102
  return node;
3963
3103
  }
@@ -3967,10 +3107,6 @@ function fieldIdFromFieldIdKey([revision, localId, field]: FieldIdKey): FieldId
3967
3107
  return { nodeId, field };
3968
3108
  }
3969
3109
 
3970
- function fieldIdKeyFromFieldId(fieldId: FieldId): FieldIdKey {
3971
- return [fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field];
3972
- }
3973
-
3974
3110
  function cloneNodeChangeset(nodeChangeset: NodeChangeset): NodeChangeset {
3975
3111
  if (nodeChangeset.fieldChanges !== undefined) {
3976
3112
  return { ...nodeChangeset, fieldChanges: new Map(nodeChangeset.fieldChanges) };
@@ -3979,15 +3115,6 @@ function cloneNodeChangeset(nodeChangeset: NodeChangeset): NodeChangeset {
3979
3115
  return { ...nodeChangeset };
3980
3116
  }
3981
3117
 
3982
- function replaceNodeLocationRevision(
3983
- location: NodeLocation,
3984
- replacer: RevisionReplacer,
3985
- ): NodeLocation {
3986
- return location.field === undefined
3987
- ? { root: replacer.getUpdatedAtomId(location.root) }
3988
- : { field: replaceFieldIdRevision(location.field, replacer) };
3989
- }
3990
-
3991
3118
  function replaceFieldIdRevision(fieldId: FieldId, replacer: RevisionReplacer): FieldId {
3992
3119
  if (fieldId.nodeId === undefined) {
3993
3120
  return fieldId;
@@ -3999,16 +3126,10 @@ function replaceFieldIdRevision(fieldId: FieldId, replacer: RevisionReplacer): F
3999
3126
  };
4000
3127
  }
4001
3128
 
4002
- export function getNodeParent(changeset: ModularChangeset, nodeId: NodeId): NodeLocation {
4003
- const normalizedNodeId = normalizeNodeId(nodeId, changeset.nodeAliases);
4004
- const location = getFromChangeAtomIdMap(changeset.nodeToParent, normalizedNodeId);
4005
- assert(location !== undefined, 0x9cb /* Parent field should be defined */);
4006
-
4007
- if (location.field !== undefined) {
4008
- return { field: normalizeFieldId(location.field, changeset.nodeAliases) };
4009
- }
4010
-
4011
- return location;
3129
+ export function getParentFieldId(changeset: ModularChangeset, nodeId: NodeId): FieldId {
3130
+ const parentId = getFromChangeAtomIdMap(changeset.nodeToParent, nodeId);
3131
+ assert(parentId !== undefined, 0x9cb /* Parent field should be defined */);
3132
+ return normalizeFieldId(parentId, changeset.nodeAliases);
4012
3133
  }
4013
3134
 
4014
3135
  function getFieldsForCrossFieldKey(
@@ -4021,30 +3142,6 @@ function getFieldsForCrossFieldKey(
4021
3142
  .map(({ value: fieldId }) => normalizeFieldId(fieldId, changeset.nodeAliases));
4022
3143
  }
4023
3144
 
4024
- function getFirstFieldForCrossFieldKey(
4025
- changeset: ModularChangeset,
4026
- key: CrossFieldKey,
4027
- count: number,
4028
- ): RangeQueryResult<FieldId | undefined> {
4029
- const result = changeset.crossFieldKeys.getFirst(key, count);
4030
- if (result.value === undefined) {
4031
- return result;
4032
- }
4033
-
4034
- return { ...result, value: normalizeFieldId(result.value, changeset.nodeAliases) };
4035
- }
4036
-
4037
- function normalizeNodeLocation(
4038
- location: NodeLocation,
4039
- nodeAliases: ChangeAtomIdBTree<NodeId>,
4040
- ): NodeLocation {
4041
- if (location.field !== undefined) {
4042
- return { field: normalizeFieldId(location.field, nodeAliases) };
4043
- }
4044
-
4045
- return location;
4046
- }
4047
-
4048
3145
  // This is only exported for use in test utilities.
4049
3146
  export function normalizeFieldId(
4050
3147
  fieldId: FieldId,
@@ -4058,12 +3155,8 @@ export function normalizeFieldId(
4058
3155
  /**
4059
3156
  * @returns The canonical form of nodeId, according to nodeAliases
4060
3157
  */
4061
- export function normalizeNodeId(
4062
- nodeId: NodeId,
4063
- nodeAliases: ChangeAtomIdBTree<NodeId>,
4064
- ): NodeId {
3158
+ function normalizeNodeId(nodeId: NodeId, nodeAliases: ChangeAtomIdBTree<NodeId>): NodeId {
4065
3159
  let currentId = nodeId;
4066
- let cycleProbeId: NodeId | undefined = nodeId;
4067
3160
 
4068
3161
  // eslint-disable-next-line no-constant-condition
4069
3162
  while (true) {
@@ -4073,16 +3166,6 @@ export function normalizeNodeId(
4073
3166
  }
4074
3167
 
4075
3168
  currentId = dealiased;
4076
-
4077
- if (cycleProbeId !== undefined) {
4078
- cycleProbeId = getFromChangeAtomIdMap(nodeAliases, cycleProbeId);
4079
- }
4080
-
4081
- if (cycleProbeId !== undefined) {
4082
- cycleProbeId = getFromChangeAtomIdMap(nodeAliases, cycleProbeId);
4083
- }
4084
-
4085
- assert(!areEqualChangeAtomIdOpts(cycleProbeId, currentId), "Alias cycle detected");
4086
3169
  }
4087
3170
  }
4088
3171
 
@@ -4090,11 +3173,23 @@ function hasConflicts(change: ModularChangeset): boolean {
4090
3173
  return (change.constraintViolationCount ?? 0) > 0;
4091
3174
  }
4092
3175
 
3176
+ /**
3177
+ * A rebaseChild callback for fields with no new changes.
3178
+ * Asserts that there are no new changes and returns undefined.
3179
+ */
3180
+ function noNewChangesRebaseChild(
3181
+ child: NodeId | undefined,
3182
+ _baseChild: NodeId | undefined,
3183
+ _stateChange: NodeAttachState | undefined,
3184
+ ): NodeId | undefined {
3185
+ assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
3186
+ return undefined;
3187
+ }
3188
+
4093
3189
  interface ModularChangesetContent {
4094
3190
  fieldChanges: FieldChangeMap;
4095
3191
  nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
4096
- nodeToParent: ChangeAtomIdBTree<NodeLocation>;
4097
- rootNodes: RootNodeTable;
3192
+ nodeToParent: ChangeAtomIdBTree<FieldId>;
4098
3193
  nodeAliases: ChangeAtomIdBTree<NodeId>;
4099
3194
  crossFieldKeys: CrossFieldKeyTable;
4100
3195
  }
@@ -4102,927 +3197,3 @@ interface ModularChangesetContent {
4102
3197
  function areEqualFieldIds(a: FieldId, b: FieldId): boolean {
4103
3198
  return areEqualChangeAtomIdOpts(a.nodeId, b.nodeId) && a.field === b.field;
4104
3199
  }
4105
-
4106
- function firstAttachIdFromDetachId(
4107
- roots: RootNodeTable,
4108
- detachId: ChangeAtomId,
4109
- count: number,
4110
- ): RangeQueryResult<ChangeAtomId> {
4111
- const result = roots.oldToNewId.getFirst(detachId, count);
4112
- return { ...result, value: result.value ?? detachId };
4113
- }
4114
-
4115
- function firstDetachIdFromAttachId(
4116
- roots: RootNodeTable,
4117
- attachId: ChangeAtomId,
4118
- count: number,
4119
- ): RangeQueryEntry<ChangeAtomId, ChangeAtomId> {
4120
- const result = roots.newToOldId.getFirst(attachId, count);
4121
- return { ...result, start: attachId, value: result.value ?? attachId };
4122
- }
4123
-
4124
- function rebaseCrossFieldKeys(
4125
- sourceTable: CrossFieldKeyTable,
4126
- movedDetaches: ChangeAtomIdRangeMap<boolean>,
4127
- newDetachLocations: ChangeAtomIdRangeMap<FieldId>,
4128
- ): CrossFieldKeyTable {
4129
- const rebasedTable = sourceTable.clone();
4130
- for (const entry of movedDetaches.entries()) {
4131
- rebasedTable.delete({ ...entry.start, target: CrossFieldTarget.Source }, entry.length);
4132
- }
4133
-
4134
- for (const entry of newDetachLocations.entries()) {
4135
- rebasedTable.set(
4136
- { ...entry.start, target: CrossFieldTarget.Source },
4137
- entry.length,
4138
- entry.value,
4139
- );
4140
- }
4141
-
4142
- return rebasedTable;
4143
- }
4144
-
4145
- export function newRootTable(): RootNodeTable {
4146
- return {
4147
- newToOldId: newChangeAtomIdTransform(),
4148
- oldToNewId: newChangeAtomIdTransform(),
4149
- nodeChanges: newTupleBTree(),
4150
- detachLocations: newChangeAtomIdRangeMap(),
4151
- outputDetachLocations: newChangeAtomIdRangeMap(),
4152
- };
4153
- }
4154
-
4155
- function rebaseRoots(
4156
- change: ModularChangeset,
4157
- base: ModularChangeset,
4158
- affectedBaseFields: TupleBTree<FieldIdKey, boolean>,
4159
- nodesToRebase: [newChangeset: NodeId, baseChangeset: NodeId][],
4160
- rebasedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
4161
- rebaseVersion: RebaseVersion,
4162
- ): RootNodeTable {
4163
- const rebasedRoots = newRootTable();
4164
- for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
4165
- rebaseRename(change.rootNodes, rebasedRoots, renameEntry, base, affectedBaseFields);
4166
- }
4167
-
4168
- for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
4169
- const changes = base.rootNodes.nodeChanges.get(detachIdKey);
4170
- if (changes !== undefined) {
4171
- nodesToRebase.push([nodeId, changes]);
4172
- }
4173
-
4174
- const detachId = makeChangeAtomId(detachIdKey[1], detachIdKey[0]);
4175
- const attachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
4176
- const baseAttachEntry = base.crossFieldKeys.getFirst(
4177
- { target: CrossFieldTarget.Destination, ...attachId },
4178
- 1,
4179
- );
4180
- if (baseAttachEntry.value === undefined) {
4181
- const renamedDetachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
4182
- const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(
4183
- renamedDetachId,
4184
- 1,
4185
- ).value;
4186
-
4187
- if (baseOutputDetachLocation !== undefined) {
4188
- affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
4189
- }
4190
-
4191
- const detachLocation =
4192
- baseOutputDetachLocation ??
4193
- change.rootNodes.detachLocations.getFirst(detachId, 1).value;
4194
-
4195
- // Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
4196
- // We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
4197
- assignRootChange(
4198
- rebasedRoots,
4199
- rebasedNodeToParent,
4200
- renamedDetachId,
4201
- nodeId,
4202
- detachLocation,
4203
- rebaseVersion,
4204
- );
4205
- } else {
4206
- affectedBaseFields.set(fieldIdKeyFromFieldId(baseAttachEntry.value), true);
4207
- rebasedNodeToParent.delete(detachIdKey);
4208
- }
4209
- }
4210
-
4211
- for (const entry of change.rootNodes.outputDetachLocations.entries()) {
4212
- rebasedRoots.outputDetachLocations.set(entry.start, entry.length, entry.value);
4213
- }
4214
-
4215
- return rebasedRoots;
4216
- }
4217
-
4218
- function rebaseRename(
4219
- newRoots: RootNodeTable,
4220
- rebasedRoots: RootNodeTable,
4221
- renameEntry: RangeQueryEntry<ChangeAtomId, ChangeAtomId>,
4222
- base: ModularChangeset,
4223
- affectedBaseFields: TupleBTree<FieldIdKey, boolean>,
4224
- ): void {
4225
- let count = renameEntry.length;
4226
- const baseRenameEntry = firstAttachIdFromDetachId(base.rootNodes, renameEntry.start, count);
4227
- count = baseRenameEntry.length;
4228
-
4229
- const baseAttachEntry = base.crossFieldKeys.getFirst(
4230
- {
4231
- ...baseRenameEntry.value,
4232
- target: CrossFieldTarget.Destination,
4233
- },
4234
- count,
4235
- );
4236
-
4237
- count = baseAttachEntry.length;
4238
-
4239
- if (baseAttachEntry.value === undefined) {
4240
- const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(
4241
- baseRenameEntry.value,
4242
- 1,
4243
- ).value;
4244
-
4245
- if (baseOutputDetachLocation !== undefined) {
4246
- affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
4247
- }
4248
-
4249
- const detachEntry = newRoots.detachLocations.getFirst(renameEntry.start, count);
4250
- count = detachEntry.length;
4251
-
4252
- const detachLocation = baseOutputDetachLocation ?? detachEntry.value;
4253
-
4254
- // Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
4255
- // We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
4256
- addNodeRename(
4257
- rebasedRoots,
4258
- baseRenameEntry.value,
4259
- renameEntry.value,
4260
- count,
4261
- detachLocation,
4262
- );
4263
- } else {
4264
- // This rename represents an intention to detach these nodes.
4265
- // The rebased change should have a detach in the field where the base change attaches the nodes,
4266
- // so we need to ensure that field is processed.
4267
- affectedBaseFields.set(
4268
- fieldIdKeyFromFieldId(normalizeFieldId(baseAttachEntry.value, base.nodeAliases)),
4269
- true,
4270
- );
4271
- }
4272
-
4273
- const countRemaining = renameEntry.length - count;
4274
- if (countRemaining > 0) {
4275
- rebaseRename(
4276
- newRoots,
4277
- rebasedRoots,
4278
- {
4279
- start: offsetChangeAtomId(renameEntry.start, count),
4280
- value: offsetChangeAtomId(renameEntry.value, count),
4281
- length: countRemaining,
4282
- },
4283
- base,
4284
- affectedBaseFields,
4285
- );
4286
- }
4287
- }
4288
-
4289
- /**
4290
- * For each root detach location, replaces any node ID from the base changeset
4291
- * with the corresponding ID in the new changeset.
4292
- */
4293
- function fixupRebasedDetachLocations(table: RebaseTable): void {
4294
- for (const {
4295
- start,
4296
- length,
4297
- value: detachLocation,
4298
- } of table.rebasedRootNodes.detachLocations.entries()) {
4299
- const normalizedDetachLocation = normalizeFieldId(
4300
- detachLocation,
4301
- table.baseChange.nodeAliases,
4302
- );
4303
-
4304
- if (normalizedDetachLocation.nodeId !== undefined) {
4305
- const rebasedNodeId = getFromChangeAtomIdMap(
4306
- table.baseToRebasedNodeId,
4307
- normalizedDetachLocation.nodeId,
4308
- );
4309
-
4310
- if (rebasedNodeId !== undefined) {
4311
- table.rebasedRootNodes.detachLocations.set(start, length, {
4312
- ...normalizedDetachLocation,
4313
- nodeId: rebasedNodeId,
4314
- });
4315
- }
4316
- }
4317
- }
4318
- }
4319
-
4320
- function addNodesToCompose(table: ComposeTable, id1: NodeId, id2: NodeId): void {
4321
- const normalizedId1 = normalizeNodeId(id1, table.baseChange.nodeAliases);
4322
- const normalizedId2 = normalizeNodeId(id2, table.newChange.nodeAliases);
4323
- if (getFromChangeAtomIdMap(table.newToBaseNodeId, normalizedId2) === undefined) {
4324
- setInChangeAtomIdMap(table.newToBaseNodeId, normalizedId2, normalizedId1);
4325
- table.pendingCompositions.nodeIdsToCompose.push([normalizedId1, normalizedId2]);
4326
- }
4327
- }
4328
-
4329
- function composeRevInfos(
4330
- revisions1: readonly RevisionInfo[] | undefined,
4331
- revisions2: readonly RevisionInfo[] | undefined,
4332
- ): readonly RevisionInfo[] {
4333
- if (
4334
- revisions1?.length === 1 &&
4335
- revisions2?.length === 1 &&
4336
- revisions1[0]?.revision === revisions2[0]?.revision
4337
- ) {
4338
- // This is a special case where we are composing two changesets from the same transaction.
4339
- // We return one of the input arrays to avoid duplicating revision entries.
4340
- return revisions1;
4341
- }
4342
- const result: RevisionInfo[] = [...(revisions1 ?? []), ...(revisions2 ?? [])];
4343
- return result;
4344
- }
4345
-
4346
- function composeCrossFieldKeyTables(
4347
- table1: CrossFieldKeyTable,
4348
- table2: CrossFieldKeyTable,
4349
- movedCrossFieldKeys: CrossFieldKeyTable,
4350
- removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
4351
- ): CrossFieldKeyTable {
4352
- const composedTable = RangeMap.union(table1, table2);
4353
- for (const entry of movedCrossFieldKeys.entries()) {
4354
- composedTable.set(entry.start, entry.length, entry.value);
4355
- }
4356
-
4357
- for (const entry of removedCrossFieldKeys.entries()) {
4358
- composedTable.delete(entry.start, entry.length);
4359
- }
4360
-
4361
- return composedTable;
4362
- }
4363
-
4364
- function composeRootTables(
4365
- change1: ModularChangeset,
4366
- change2: ModularChangeset,
4367
- composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
4368
- movedCrossFieldKeys: CrossFieldKeyTable,
4369
- removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
4370
- pendingCompositions: PendingCompositions,
4371
- ): RootNodeTable {
4372
- const composedTable = cloneRootTable(change1.rootNodes);
4373
-
4374
- for (const renameEntry of change2.rootNodes.oldToNewId.entries()) {
4375
- composeRename(
4376
- change1,
4377
- change2,
4378
- composedTable,
4379
- renameEntry.start,
4380
- renameEntry.value,
4381
- renameEntry.length,
4382
- movedCrossFieldKeys,
4383
- removedCrossFieldKeys,
4384
- pendingCompositions,
4385
- );
4386
- }
4387
-
4388
- for (const [[revision2, id2], nodeId2] of change2.rootNodes.nodeChanges.entries()) {
4389
- const detachId2 = { revision: revision2, localId: id2 };
4390
- const detachId1 = firstDetachIdFromAttachId(change1.rootNodes, detachId2, 1).value;
4391
- const nodeId1 = getFromChangeAtomIdMap(change1.rootNodes.nodeChanges, detachId1);
4392
-
4393
- if (nodeId1 === undefined) {
4394
- const fieldId = getFieldsForCrossFieldKey(
4395
- change1,
4396
- { ...detachId1, target: CrossFieldTarget.Source },
4397
- 1,
4398
- )[0];
4399
-
4400
- if (fieldId === undefined) {
4401
- assignRootChange(
4402
- composedTable,
4403
- composedNodeToParent,
4404
- detachId1,
4405
- nodeId2,
4406
- change1.rootNodes.detachLocations.getFirst(detachId1, 1).value ??
4407
- change2.rootNodes.detachLocations.getFirst(detachId2, 1).value,
4408
- Math.max(change1.rebaseVersion, change2.rebaseVersion) as RebaseVersion,
4409
- );
4410
- } else {
4411
- // In this case, this node is attached in the input context of change1,
4412
- // and is represented in detachFieldId.
4413
- pendingCompositions.affectedBaseFields.set(
4414
- [fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field],
4415
- true,
4416
- );
4417
- }
4418
- } else {
4419
- pendingCompositions.nodeIdsToCompose.push([nodeId1, nodeId2]);
4420
- }
4421
- }
4422
-
4423
- for (const outputDetachEntry of change1.rootNodes.outputDetachLocations.entries()) {
4424
- composeOutputDetachLocation(
4425
- outputDetachEntry.start,
4426
- outputDetachEntry.length,
4427
- outputDetachEntry.value,
4428
- change2,
4429
- composedTable,
4430
- );
4431
- }
4432
-
4433
- for (const entry of change2.rootNodes.outputDetachLocations.entries()) {
4434
- composedTable.outputDetachLocations.set(entry.start, entry.length, entry.value);
4435
- }
4436
-
4437
- return composedTable;
4438
- }
4439
-
4440
- function composeOutputDetachLocation(
4441
- outputDetachId1: ChangeAtomId,
4442
- count: number,
4443
- detachLocation: FieldId,
4444
- change2: ModularChangeset,
4445
- composedTable: RootNodeTable,
4446
- ): void {
4447
- let countToProcess = count;
4448
- const renameEntry = firstAttachIdFromDetachId(
4449
- change2.rootNodes,
4450
- outputDetachId1,
4451
- countToProcess,
4452
- );
4453
- countToProcess = renameEntry.length;
4454
-
4455
- const attachEntry = getFirstAttachField(
4456
- change2.crossFieldKeys,
4457
- renameEntry.value,
4458
- countToProcess,
4459
- );
4460
- countToProcess = attachEntry.length;
4461
-
4462
- composedTable.outputDetachLocations.delete(outputDetachId1, countToProcess);
4463
-
4464
- if (attachEntry.value === undefined) {
4465
- // We update the key for the detach location to the renamed ID of the root in the composed output context.
4466
- composedTable.outputDetachLocations.set(renameEntry.value, countToProcess, detachLocation);
4467
- } else {
4468
- // These nodes are attached by `change2` and thus attached in the composed output context,
4469
- // so there should be no output detach location.
4470
- }
4471
-
4472
- const countRemaining = count - countToProcess;
4473
- if (countRemaining > 0) {
4474
- composeOutputDetachLocation(
4475
- offsetChangeAtomId(outputDetachId1, countToProcess),
4476
- countRemaining,
4477
- detachLocation,
4478
- change2,
4479
- composedTable,
4480
- );
4481
- }
4482
- }
4483
-
4484
- function composeRename(
4485
- change1: ModularChangeset,
4486
- change2: ModularChangeset,
4487
- mergedTable: RootNodeTable,
4488
- oldId: ChangeAtomId,
4489
- newId: ChangeAtomId,
4490
- count: number,
4491
- movedCrossFieldKeys: CrossFieldKeyTable,
4492
- removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
4493
- pendingCompositions: PendingCompositions,
4494
- ): void {
4495
- let countToProcess = count;
4496
- const detachEntry = getFirstDetachField(change1.crossFieldKeys, oldId, countToProcess);
4497
- countToProcess = detachEntry.length;
4498
-
4499
- if (detachEntry.value === undefined) {
4500
- // `change1` may also have a rename to `renameEntry.value`, in which case it must refer to a different node.
4501
- // That node must have been attached by `change1` and detached by `change2`.
4502
- // The final rename for that node will be created in `composeAttachDetach`.
4503
- // We delete any such rename for now to avoid colliding with the rename currently being processed.
4504
- deleteNodeRenameTo(mergedTable, newId, countToProcess);
4505
-
4506
- // The nodes were detached before `change`, so we append this rename.
4507
- appendNodeRename(
4508
- mergedTable,
4509
- oldId,
4510
- newId,
4511
- countToProcess,
4512
- change1.rootNodes,
4513
- change2.rootNodes.detachLocations.getFirst(oldId, countToProcess).value,
4514
- );
4515
- } else {
4516
- // `change1` detached these nodes,
4517
- // so we invalidate the detach location so that the detach's ID can be replaced with the new ID.
4518
- pendingCompositions.affectedBaseFields.set(fieldIdKeyFromFieldId(detachEntry.value), true);
4519
-
4520
- if (!areEqualChangeAtomIds(oldId, newId)) {
4521
- // `change1`'s detach will be replaced by `change2`'s detach, so we update the cross-field keys.
4522
- removedCrossFieldKeys.set(
4523
- { ...oldId, target: CrossFieldTarget.Source },
4524
- countToProcess,
4525
- true,
4526
- );
4527
- }
4528
-
4529
- movedCrossFieldKeys.set(
4530
- { ...newId, target: CrossFieldTarget.Source },
4531
- countToProcess,
4532
- detachEntry.value,
4533
- );
4534
- }
4535
-
4536
- if (countToProcess < count) {
4537
- composeRename(
4538
- change1,
4539
- change2,
4540
- mergedTable,
4541
- offsetChangeAtomId(oldId, countToProcess),
4542
- offsetChangeAtomId(newId, countToProcess),
4543
- count - countToProcess,
4544
- movedCrossFieldKeys,
4545
- removedCrossFieldKeys,
4546
- pendingCompositions,
4547
- );
4548
- }
4549
- }
4550
-
4551
- export function cloneRootTable(table: RootNodeTable): RootNodeTable {
4552
- return {
4553
- oldToNewId: table.oldToNewId.clone(),
4554
- newToOldId: table.newToOldId.clone(),
4555
- nodeChanges: brand(table.nodeChanges.clone()),
4556
- detachLocations: table.detachLocations.clone(),
4557
- outputDetachLocations: table.outputDetachLocations.clone(),
4558
- };
4559
- }
4560
-
4561
- function invertRootTable(change: ModularChangeset, isRollback: boolean): RootNodeTable {
4562
- const invertedRoots: RootNodeTable = newRootTable();
4563
- for (const [[revision, localId], nodeId] of change.rootNodes.nodeChanges.entries()) {
4564
- const detachId: ChangeAtomId = { revision, localId };
4565
- const renamedId = firstAttachIdFromDetachId(change.rootNodes, detachId, 1).value;
4566
-
4567
- // This checks whether `change` attaches this node.
4568
- // 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.
4569
- if (
4570
- change.crossFieldKeys.getFirst({ ...renamedId, target: CrossFieldTarget.Destination }, 1)
4571
- .value === undefined
4572
- ) {
4573
- assignRootChange(
4574
- invertedRoots,
4575
- undefined,
4576
- renamedId,
4577
- nodeId,
4578
- change.rootNodes.detachLocations.getFirst(detachId, 1).value,
4579
- change.rebaseVersion,
4580
- );
4581
- }
4582
- }
4583
-
4584
- if (isRollback) {
4585
- // We only invert renames of nodes which are not attached or detached by this changeset.
4586
- // When we invert an attach we will create a detach which incorporates the rename.
4587
- for (const {
4588
- start: oldId,
4589
- value: newId,
4590
- length,
4591
- } of change.rootNodes.oldToNewId.entries()) {
4592
- invertRename(change, invertedRoots, oldId, newId, length);
4593
- }
4594
- }
4595
-
4596
- return invertedRoots;
4597
- }
4598
-
4599
- function invertRename(
4600
- change: ModularChangeset,
4601
- invertedRoots: RootNodeTable,
4602
- oldId: ChangeAtomId,
4603
- newId: ChangeAtomId,
4604
- length: number,
4605
- ): void {
4606
- for (const detachEntry of doesChangeDetachNodes(change.crossFieldKeys, newId, length)) {
4607
- assert(
4608
- !detachEntry.value,
4609
- "A changeset should not have a rename and detach for the same node.",
4610
- );
4611
- }
4612
-
4613
- let countProcessed = length;
4614
- const attachEntry = getFirstAttachField(change.crossFieldKeys, newId, countProcessed);
4615
- countProcessed = attachEntry.length;
4616
- if (attachEntry.value === undefined) {
4617
- const outputDetachEntry = change.rootNodes.outputDetachLocations.getFirst(
4618
- newId,
4619
- countProcessed,
4620
- );
4621
- countProcessed = outputDetachEntry.length;
4622
-
4623
- const inputDetachEntry = change.rootNodes.detachLocations.getFirst(oldId, countProcessed);
4624
- countProcessed = inputDetachEntry.length;
4625
-
4626
- addNodeRename(
4627
- invertedRoots,
4628
- newId,
4629
- oldId,
4630
- countProcessed,
4631
- outputDetachEntry.value ?? inputDetachEntry.value,
4632
- );
4633
- }
4634
-
4635
- if (countProcessed < length) {
4636
- invertRename(
4637
- change,
4638
- invertedRoots,
4639
- offsetChangeAtomId(oldId, countProcessed),
4640
- offsetChangeAtomId(newId, countProcessed),
4641
- length - countProcessed,
4642
- );
4643
- }
4644
- }
4645
-
4646
- function doesChangeAttachNodes(
4647
- table: CrossFieldKeyTable,
4648
- id: ChangeAtomId,
4649
- count: number,
4650
- ): RangeQueryResultFragment<boolean>[] {
4651
- return table
4652
- .getAll2({ ...id, target: CrossFieldTarget.Destination }, count)
4653
- .map((entry) => ({ ...entry, value: entry.value !== undefined }));
4654
- }
4655
-
4656
- function doesChangeDetachNodes(
4657
- table: CrossFieldKeyTable,
4658
- id: ChangeAtomId,
4659
- count: number,
4660
- ): RangeQueryResultFragment<boolean>[] {
4661
- return table
4662
- .getAll2({ ...id, target: CrossFieldTarget.Source }, count)
4663
- .map((entry) => ({ ...entry, value: entry.value !== undefined }));
4664
- }
4665
-
4666
- export function getFirstDetachField(
4667
- table: CrossFieldKeyTable,
4668
- id: ChangeAtomId,
4669
- count: number,
4670
- ): RangeQueryResult<FieldId | undefined> {
4671
- return table.getFirst({ target: CrossFieldTarget.Source, ...id }, count);
4672
- }
4673
-
4674
- export function getFirstAttachField(
4675
- table: CrossFieldKeyTable,
4676
- id: ChangeAtomId,
4677
- count: number,
4678
- ): RangeQueryResult<FieldId | undefined> {
4679
- return table.getFirst({ target: CrossFieldTarget.Destination, ...id }, count);
4680
- }
4681
-
4682
- export function addNodeRename(
4683
- table: RootNodeTable,
4684
- oldId: ChangeAtomId,
4685
- newId: ChangeAtomId,
4686
- count: number,
4687
- detachLocation: FieldId | undefined,
4688
- ): void {
4689
- if (areEqualChangeAtomIds(oldId, newId)) {
4690
- return;
4691
- }
4692
-
4693
- for (const entry of table.oldToNewId.getAll2(oldId, count)) {
4694
- assert(
4695
- entry.value === undefined ||
4696
- areEqualChangeAtomIds(entry.value, offsetChangeAtomId(newId, entry.offset)),
4697
- "Rename collision detected",
4698
- );
4699
- }
4700
-
4701
- for (const entry of table.newToOldId.getAll2(newId, count)) {
4702
- assert(
4703
- entry.value === undefined ||
4704
- areEqualChangeAtomIds(entry.value, offsetChangeAtomId(oldId, entry.offset)),
4705
- "Rename collision detected",
4706
- );
4707
- }
4708
-
4709
- table.oldToNewId.set(oldId, count, newId);
4710
- table.newToOldId.set(newId, count, oldId);
4711
-
4712
- if (detachLocation !== undefined) {
4713
- table.detachLocations.set(oldId, count, detachLocation);
4714
- }
4715
- }
4716
-
4717
- /**
4718
- * Deletes any renames from `id`.
4719
- */
4720
- function deleteNodeRenameFrom(roots: RootNodeTable, id: ChangeAtomId, count: number): void {
4721
- for (const entry of roots.oldToNewId.getAll(id, count)) {
4722
- deleteNodeRenameEntry(roots, entry.start, entry.value, entry.length);
4723
- }
4724
- }
4725
-
4726
- /**
4727
- * Deletes any renames to `id`.
4728
- */
4729
- function deleteNodeRenameTo(roots: RootNodeTable, id: ChangeAtomId, count: number): void {
4730
- for (const entry of roots.newToOldId.getAll(id, count)) {
4731
- deleteNodeRenameEntry(roots, entry.value, entry.start, entry.length);
4732
- }
4733
- }
4734
-
4735
- function appendNodeRename(
4736
- composedTable: RootNodeTable,
4737
- oldId: ChangeAtomId,
4738
- newId: ChangeAtomId,
4739
- count: number,
4740
- change1Table: RootNodeTable,
4741
- detachLocation: FieldId | undefined,
4742
- ): void {
4743
- let countToProcess = count;
4744
- const rename1Entry = change1Table.newToOldId.getFirst(oldId, countToProcess);
4745
- countToProcess = rename1Entry.length;
4746
-
4747
- if (rename1Entry.value !== undefined) {
4748
- deleteNodeRenameFrom(composedTable, rename1Entry.value, countToProcess);
4749
- }
4750
-
4751
- addNodeRename(
4752
- composedTable,
4753
- rename1Entry.value ?? oldId,
4754
- newId,
4755
- countToProcess,
4756
- detachLocation,
4757
- );
4758
-
4759
- tryRemoveDetachLocation(composedTable, newId, countToProcess);
4760
-
4761
- if (countToProcess < count) {
4762
- const countRemaining = count - countToProcess;
4763
- appendNodeRename(
4764
- composedTable,
4765
- offsetChangeAtomId(oldId, countToProcess),
4766
- offsetChangeAtomId(newId, countToProcess),
4767
- countRemaining,
4768
- change1Table,
4769
- detachLocation,
4770
- );
4771
- }
4772
- }
4773
-
4774
- function tryRemoveDetachLocation(
4775
- roots: RootNodeTable,
4776
- rootId: ChangeAtomId,
4777
- count: number,
4778
- ): void {
4779
- let countProcessed = count;
4780
- const renameEntry = roots.oldToNewId.getFirst(rootId, countProcessed);
4781
- countProcessed = renameEntry.length;
4782
-
4783
- const outputDetachEntry = roots.outputDetachLocations.getFirst(rootId, countProcessed);
4784
- countProcessed = outputDetachEntry.length;
4785
-
4786
- const nodeChangeEntry = rangeQueryChangeAtomIdMap(roots.nodeChanges, rootId, countProcessed);
4787
- countProcessed = nodeChangeEntry.length;
4788
-
4789
- if (
4790
- nodeChangeEntry.value === undefined &&
4791
- renameEntry.value === undefined &&
4792
- outputDetachEntry.value === undefined
4793
- ) {
4794
- roots.detachLocations.delete(rootId, countProcessed);
4795
- }
4796
-
4797
- const countRemaining = count - countProcessed;
4798
- if (countRemaining > 0) {
4799
- tryRemoveDetachLocation(roots, offsetChangeAtomId(rootId, countProcessed), countRemaining);
4800
- }
4801
- }
4802
-
4803
- /**
4804
- * Deletes the entry renaming the ID range of length `count` from `oldId` to `newId`.
4805
- * This function assumes that such an entry exists.
4806
- */
4807
- function deleteNodeRenameEntry(
4808
- roots: RootNodeTable,
4809
- oldId: ChangeAtomId,
4810
- newId: ChangeAtomId,
4811
- count: number,
4812
- ): void {
4813
- roots.oldToNewId.delete(oldId, count);
4814
- roots.newToOldId.delete(newId, count);
4815
- }
4816
-
4817
- function replaceRootTableRevision(
4818
- table: RootNodeTable,
4819
- replacer: RevisionReplacer,
4820
- nodeAliases: ChangeAtomIdBTree<NodeId>,
4821
- ): RootNodeTable {
4822
- const oldToNewId = table.oldToNewId.mapEntries(
4823
- (id) => replacer.getUpdatedAtomId(id),
4824
- (id) => replacer.getUpdatedAtomId(id),
4825
- );
4826
-
4827
- const newToOldId = table.newToOldId.mapEntries(
4828
- (id) => replacer.getUpdatedAtomId(id),
4829
- (id) => replacer.getUpdatedAtomId(id),
4830
- );
4831
-
4832
- const nodeChanges: ChangeAtomIdBTree<NodeId> = replaceIdMapRevisions(
4833
- table.nodeChanges,
4834
- replacer,
4835
- (nodeId) => replacer.getUpdatedAtomId(normalizeNodeId(nodeId, nodeAliases)),
4836
- );
4837
-
4838
- const detachLocations = table.detachLocations.mapEntries(
4839
- (id) => replacer.getUpdatedAtomId(id),
4840
- (fieldId) => replaceFieldIdRevision(normalizeFieldId(fieldId, nodeAliases), replacer),
4841
- );
4842
-
4843
- const outputDetachLocations = table.outputDetachLocations.mapEntries(
4844
- (id) => replacer.getUpdatedAtomId(id),
4845
- (fieldId) => replaceFieldIdRevision(normalizeFieldId(fieldId, nodeAliases), replacer),
4846
- );
4847
-
4848
- return { oldToNewId, newToOldId, nodeChanges, detachLocations, outputDetachLocations };
4849
- }
4850
-
4851
- function newDetachedEntryMap(): ChangeAtomIdRangeMap<DetachedNodeEntry> {
4852
- return new RangeMap(offsetChangeAtomId, subtractChangeAtomIds, offsetDetachedNodeEntry);
4853
- }
4854
-
4855
- function offsetDetachedNodeEntry(entry: DetachedNodeEntry, count: number): DetachedNodeEntry {
4856
- assert(
4857
- count <= 1 || entry.nodeChange === undefined,
4858
- "Cannot split an entry with a node change",
4859
- );
4860
-
4861
- return entry.detachId === undefined
4862
- ? entry
4863
- : { ...entry, detachId: offsetChangeAtomId(entry.detachId, count) };
4864
- }
4865
-
4866
- function getFieldsWithRootMoves(
4867
- roots: RootNodeTable,
4868
- nodeAliases: ChangeAtomIdBTree<NodeId>,
4869
- ): TupleBTree<FieldIdKey, boolean> {
4870
- const fields: TupleBTree<FieldIdKey, boolean> = newTupleBTree();
4871
- for (const { start: rootId, value: fieldId, length } of roots.detachLocations.entries()) {
4872
- let isRootMoved = false;
4873
- for (const renameEntry of roots.oldToNewId.getAll2(rootId, length)) {
4874
- if (renameEntry.value !== undefined) {
4875
- isRootMoved = true;
4876
- }
4877
- }
4878
-
4879
- for (const outputDetachEntry of roots.outputDetachLocations.getAll2(rootId, length)) {
4880
- if (outputDetachEntry.value !== undefined) {
4881
- isRootMoved = true;
4882
- }
4883
- }
4884
-
4885
- if (isRootMoved) {
4886
- fields.set(fieldIdKeyFromFieldId(normalizeFieldId(fieldId, nodeAliases)), true);
4887
- }
4888
- }
4889
-
4890
- return fields;
4891
- }
4892
-
4893
- function getFieldToRootChanges(
4894
- roots: RootNodeTable,
4895
- nodeAliases: ChangeAtomIdBTree<NodeId>,
4896
- ): TupleBTree<FieldIdKey, ChangeAtomId[]> {
4897
- const fields: TupleBTree<FieldIdKey, ChangeAtomId[]> = newTupleBTree();
4898
- for (const rootIdKey of roots.nodeChanges.keys()) {
4899
- const rootId: ChangeAtomId = { revision: rootIdKey[0], localId: rootIdKey[1] };
4900
- const detachLocation = roots.detachLocations.getFirst(rootId, 1).value;
4901
- if (detachLocation !== undefined) {
4902
- const fieldIdKey = fieldIdKeyFromFieldId(normalizeFieldId(detachLocation, nodeAliases));
4903
- let rootsInField = fields.get(fieldIdKey);
4904
- if (rootsInField === undefined) {
4905
- rootsInField = [];
4906
- fields.set(fieldIdKey, rootsInField);
4907
- }
4908
-
4909
- rootsInField.push(rootId);
4910
- }
4911
- }
4912
-
4913
- return fields;
4914
- }
4915
-
4916
- function muteRootChanges(roots: RootNodeTable): RootNodeTable {
4917
- return {
4918
- oldToNewId: newChangeAtomIdTransform(),
4919
- newToOldId: newChangeAtomIdTransform(),
4920
- nodeChanges: brand(roots.nodeChanges.clone()),
4921
- detachLocations: roots.detachLocations.clone(),
4922
- outputDetachLocations: newChangeAtomIdRangeMap(),
4923
- };
4924
- }
4925
-
4926
- export function validateChangeset(
4927
- change: ModularChangeset,
4928
- fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
4929
- ): void {
4930
- const unreachableNodes: ChangeAtomIdBTree<NodeLocation> = brand(change.nodeToParent.clone());
4931
-
4932
- const unreachableCFKs = change.crossFieldKeys.clone();
4933
-
4934
- validateFieldChanges(
4935
- fieldKinds,
4936
- change,
4937
- change.fieldChanges,
4938
- undefined,
4939
- unreachableNodes,
4940
- unreachableCFKs,
4941
- );
4942
-
4943
- for (const [[revision, localId], node] of change.nodeChanges.entries()) {
4944
- if (node.fieldChanges === undefined) {
4945
- continue;
4946
- }
4947
-
4948
- const nodeId = normalizeNodeId({ revision, localId }, change.nodeAliases);
4949
- validateFieldChanges(
4950
- fieldKinds,
4951
- change,
4952
- node.fieldChanges,
4953
- nodeId,
4954
- unreachableNodes,
4955
- unreachableCFKs,
4956
- );
4957
- }
4958
-
4959
- for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
4960
- const detachId: ChangeAtomId = { revision: detachIdKey[0], localId: detachIdKey[1] };
4961
- const location = getNodeParent(change, nodeId);
4962
- assert(areEqualChangeAtomIdOpts(location.root, detachId), "Inconsistent node location");
4963
-
4964
- const normalizedNodeId = normalizeNodeId(nodeId, change.nodeAliases);
4965
- unreachableNodes.delete([normalizedNodeId.revision, normalizedNodeId.localId]);
4966
-
4967
- const fieldChanges = nodeChangeFromId(
4968
- change.nodeChanges,
4969
- change.nodeAliases,
4970
- nodeId,
4971
- ).fieldChanges;
4972
-
4973
- if (fieldChanges !== undefined) {
4974
- validateFieldChanges(
4975
- fieldKinds,
4976
- change,
4977
- fieldChanges,
4978
- normalizedNodeId,
4979
- unreachableNodes,
4980
- unreachableCFKs,
4981
- );
4982
- }
4983
- }
4984
-
4985
- assert(unreachableNodes.size === 0, "Unreachable nodes found");
4986
- assert(unreachableCFKs.entries().length === 0, "Unreachable cross-field keys found");
4987
- }
4988
-
4989
- /**
4990
- * Asserts that each node has a correct entry in `change.nodeToParent`,
4991
- * and each cross field key has a correct entry in `change.crossFieldKeys`.
4992
- * @returns the number of children found.
4993
- */
4994
- function validateFieldChanges(
4995
- fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
4996
- change: ModularChangeset,
4997
- fieldChanges: FieldChangeMap,
4998
- nodeParent: NodeId | undefined,
4999
- unreachableNodes: ChangeAtomIdBTree<NodeLocation>,
5000
- unreachableCFKs: CrossFieldRangeTable<FieldId>,
5001
- ): void {
5002
- for (const [field, fieldChange] of fieldChanges.entries()) {
5003
- const fieldId = { nodeId: nodeParent, field };
5004
- const handler = getChangeHandler(fieldKinds, fieldChange.fieldKind);
5005
- for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
5006
- const parentFieldId = getNodeParent(change, child);
5007
- assert(
5008
- parentFieldId.field !== undefined && areEqualFieldIds(parentFieldId.field, fieldId),
5009
- 0xa4e /* Inconsistent node parentage */,
5010
- );
5011
-
5012
- unreachableNodes.delete([child.revision, child.localId]);
5013
- }
5014
-
5015
- for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
5016
- const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
5017
- assert(fields.length > 0, "Unregistered cross-field key");
5018
- for (const fieldFromLookup of fields) {
5019
- assert(
5020
- areEqualFieldIds(fieldFromLookup, fieldId),
5021
- 0xa4f /* Inconsistent cross field keys */,
5022
- );
5023
- }
5024
-
5025
- unreachableCFKs.delete(keyRange.key, keyRange.count);
5026
- }
5027
- }
5028
- }