@fluidframework/tree 2.74.0-365691 → 2.74.0-370705

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