@fluidframework/tree 2.73.0 → 2.74.0-368706

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