@fluidframework/tree 2.13.0 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/api-report/tree.alpha.api.md +22 -12
  3. package/api-report/tree.beta.api.md +9 -5
  4. package/api-report/tree.legacy.alpha.api.md +9 -5
  5. package/api-report/tree.legacy.public.api.md +9 -5
  6. package/api-report/tree.public.api.md +9 -5
  7. package/assertTagging.config.mjs +14 -0
  8. package/dist/alpha.d.ts +3 -0
  9. package/dist/core/index.d.ts +2 -2
  10. package/dist/core/index.d.ts.map +1 -1
  11. package/dist/core/index.js +6 -4
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/rebase/index.d.ts +2 -2
  14. package/dist/core/rebase/index.d.ts.map +1 -1
  15. package/dist/core/rebase/index.js +5 -1
  16. package/dist/core/rebase/index.js.map +1 -1
  17. package/dist/core/rebase/types.d.ts +5 -4
  18. package/dist/core/rebase/types.d.ts.map +1 -1
  19. package/dist/core/rebase/types.js +29 -1
  20. package/dist/core/rebase/types.js.map +1 -1
  21. package/dist/core/rebase/utils.d.ts +10 -0
  22. package/dist/core/rebase/utils.d.ts.map +1 -1
  23. package/dist/core/rebase/utils.js +22 -1
  24. package/dist/core/rebase/utils.js.map +1 -1
  25. package/dist/core/tree/delta.d.ts +21 -26
  26. package/dist/core/tree/delta.d.ts.map +1 -1
  27. package/dist/core/tree/delta.js.map +1 -1
  28. package/dist/core/tree/deltaUtil.d.ts +1 -3
  29. package/dist/core/tree/deltaUtil.d.ts.map +1 -1
  30. package/dist/core/tree/deltaUtil.js +2 -14
  31. package/dist/core/tree/deltaUtil.js.map +1 -1
  32. package/dist/core/tree/index.d.ts +1 -1
  33. package/dist/core/tree/index.d.ts.map +1 -1
  34. package/dist/core/tree/index.js +1 -3
  35. package/dist/core/tree/index.js.map +1 -1
  36. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  37. package/dist/core/tree/visitDelta.js +82 -80
  38. package/dist/core/tree/visitDelta.js.map +1 -1
  39. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  40. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  41. package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
  42. package/dist/feature-libraries/deltaUtils.js +13 -0
  43. package/dist/feature-libraries/deltaUtils.js.map +1 -1
  44. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  45. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  46. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  47. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +5 -5
  48. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  49. package/dist/feature-libraries/modular-schema/crossFieldQueries.js +2 -9
  50. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  51. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +19 -2
  52. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  53. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  54. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  55. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  56. package/dist/feature-libraries/modular-schema/index.d.ts +2 -2
  57. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  58. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  59. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  60. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  61. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +8 -8
  62. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  63. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +4 -4
  64. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  65. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +105 -199
  66. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  67. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +11 -20
  68. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  69. package/dist/feature-libraries/modular-schema/modularChangeTypes.js +20 -0
  70. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  71. package/dist/feature-libraries/optional-field/optionalField.d.ts +3 -3
  72. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  73. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  74. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  75. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  76. package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  77. package/dist/feature-libraries/sequence-field/rebase.js +4 -4
  78. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  79. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  80. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  81. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  82. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  83. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  84. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  85. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  86. package/dist/feature-libraries/sequence-field/utils.js +36 -4
  87. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  88. package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  89. package/dist/feature-libraries/treeCursorUtils.js +4 -1
  90. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  91. package/dist/index.d.ts +26 -2
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +4 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/package.json +2 -1
  96. package/dist/packageVersion.d.ts +1 -1
  97. package/dist/packageVersion.js +1 -1
  98. package/dist/packageVersion.js.map +1 -1
  99. package/dist/shared-tree/index.d.ts +1 -1
  100. package/dist/shared-tree/index.d.ts.map +1 -1
  101. package/dist/shared-tree/index.js +4 -2
  102. package/dist/shared-tree/index.js.map +1 -1
  103. package/dist/shared-tree/sharedTree.d.ts +38 -18
  104. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  105. package/dist/shared-tree/sharedTree.js +38 -34
  106. package/dist/shared-tree/sharedTree.js.map +1 -1
  107. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  108. package/dist/shared-tree/treeCheckout.js +12 -8
  109. package/dist/shared-tree/treeCheckout.js.map +1 -1
  110. package/dist/simple-tree/api/treeNodeApi.js +1 -1
  111. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  112. package/dist/simple-tree/arrayNode.js +1 -1
  113. package/dist/simple-tree/arrayNode.js.map +1 -1
  114. package/dist/simple-tree/toMapTree.js +1 -1
  115. package/dist/simple-tree/toMapTree.js.map +1 -1
  116. package/dist/util/bTreeUtils.d.ts +10 -0
  117. package/dist/util/bTreeUtils.d.ts.map +1 -0
  118. package/dist/util/bTreeUtils.js +52 -0
  119. package/dist/util/bTreeUtils.js.map +1 -0
  120. package/dist/util/idAllocator.d.ts +0 -2
  121. package/dist/util/idAllocator.d.ts.map +1 -1
  122. package/dist/util/idAllocator.js +0 -2
  123. package/dist/util/idAllocator.js.map +1 -1
  124. package/dist/util/index.d.ts +2 -1
  125. package/dist/util/index.d.ts.map +1 -1
  126. package/dist/util/index.js +5 -1
  127. package/dist/util/index.js.map +1 -1
  128. package/dist/util/rangeMap.d.ts +52 -30
  129. package/dist/util/rangeMap.d.ts.map +1 -1
  130. package/dist/util/rangeMap.js +161 -117
  131. package/dist/util/rangeMap.js.map +1 -1
  132. package/dist/util/utils.d.ts +4 -1
  133. package/dist/util/utils.d.ts.map +1 -1
  134. package/dist/util/utils.js +7 -1
  135. package/dist/util/utils.js.map +1 -1
  136. package/lib/alpha.d.ts +3 -0
  137. package/lib/core/index.d.ts +2 -2
  138. package/lib/core/index.d.ts.map +1 -1
  139. package/lib/core/index.js +2 -2
  140. package/lib/core/index.js.map +1 -1
  141. package/lib/core/rebase/index.d.ts +2 -2
  142. package/lib/core/rebase/index.d.ts.map +1 -1
  143. package/lib/core/rebase/index.js +2 -2
  144. package/lib/core/rebase/index.js.map +1 -1
  145. package/lib/core/rebase/types.d.ts +5 -4
  146. package/lib/core/rebase/types.d.ts.map +1 -1
  147. package/lib/core/rebase/types.js +26 -1
  148. package/lib/core/rebase/types.js.map +1 -1
  149. package/lib/core/rebase/utils.d.ts +10 -0
  150. package/lib/core/rebase/utils.d.ts.map +1 -1
  151. package/lib/core/rebase/utils.js +20 -0
  152. package/lib/core/rebase/utils.js.map +1 -1
  153. package/lib/core/tree/delta.d.ts +21 -26
  154. package/lib/core/tree/delta.d.ts.map +1 -1
  155. package/lib/core/tree/delta.js.map +1 -1
  156. package/lib/core/tree/deltaUtil.d.ts +1 -3
  157. package/lib/core/tree/deltaUtil.d.ts.map +1 -1
  158. package/lib/core/tree/deltaUtil.js +1 -12
  159. package/lib/core/tree/deltaUtil.js.map +1 -1
  160. package/lib/core/tree/index.d.ts +1 -1
  161. package/lib/core/tree/index.d.ts.map +1 -1
  162. package/lib/core/tree/index.js +1 -1
  163. package/lib/core/tree/index.js.map +1 -1
  164. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  165. package/lib/core/tree/visitDelta.js +82 -80
  166. package/lib/core/tree/visitDelta.js.map +1 -1
  167. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  168. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  169. package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
  170. package/lib/feature-libraries/deltaUtils.js +13 -0
  171. package/lib/feature-libraries/deltaUtils.js.map +1 -1
  172. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  173. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  174. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  175. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +5 -5
  176. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  177. package/lib/feature-libraries/modular-schema/crossFieldQueries.js +2 -9
  178. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  179. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +19 -2
  180. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  181. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  182. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  183. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  184. package/lib/feature-libraries/modular-schema/index.d.ts +2 -2
  185. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  186. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  187. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  188. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  189. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  190. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  191. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +4 -4
  192. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  193. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +74 -166
  194. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  195. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +11 -20
  196. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  197. package/lib/feature-libraries/modular-schema/modularChangeTypes.js +18 -1
  198. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  199. package/lib/feature-libraries/optional-field/optionalField.d.ts +3 -3
  200. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  201. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  202. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  203. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  204. package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  205. package/lib/feature-libraries/sequence-field/rebase.js +4 -4
  206. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  207. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  208. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  209. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  210. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  211. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  212. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  213. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  214. package/lib/feature-libraries/sequence-field/utils.js +36 -4
  215. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  216. package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  217. package/lib/feature-libraries/treeCursorUtils.js +4 -1
  218. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  219. package/lib/index.d.ts +26 -2
  220. package/lib/index.d.ts.map +1 -1
  221. package/lib/index.js +1 -1
  222. package/lib/index.js.map +1 -1
  223. package/lib/packageVersion.d.ts +1 -1
  224. package/lib/packageVersion.js +1 -1
  225. package/lib/packageVersion.js.map +1 -1
  226. package/lib/shared-tree/index.d.ts +1 -1
  227. package/lib/shared-tree/index.d.ts.map +1 -1
  228. package/lib/shared-tree/index.js +1 -1
  229. package/lib/shared-tree/index.js.map +1 -1
  230. package/lib/shared-tree/sharedTree.d.ts +38 -18
  231. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  232. package/lib/shared-tree/sharedTree.js +37 -33
  233. package/lib/shared-tree/sharedTree.js.map +1 -1
  234. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  235. package/lib/shared-tree/treeCheckout.js +13 -9
  236. package/lib/shared-tree/treeCheckout.js.map +1 -1
  237. package/lib/simple-tree/api/treeNodeApi.js +1 -1
  238. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  239. package/lib/simple-tree/arrayNode.js +1 -1
  240. package/lib/simple-tree/arrayNode.js.map +1 -1
  241. package/lib/simple-tree/toMapTree.js +1 -1
  242. package/lib/simple-tree/toMapTree.js.map +1 -1
  243. package/lib/util/bTreeUtils.d.ts +10 -0
  244. package/lib/util/bTreeUtils.d.ts.map +1 -0
  245. package/lib/util/bTreeUtils.js +47 -0
  246. package/lib/util/bTreeUtils.js.map +1 -0
  247. package/lib/util/idAllocator.d.ts +0 -2
  248. package/lib/util/idAllocator.d.ts.map +1 -1
  249. package/lib/util/idAllocator.js +0 -2
  250. package/lib/util/idAllocator.js.map +1 -1
  251. package/lib/util/index.d.ts +2 -1
  252. package/lib/util/index.d.ts.map +1 -1
  253. package/lib/util/index.js +2 -1
  254. package/lib/util/index.js.map +1 -1
  255. package/lib/util/rangeMap.d.ts +52 -30
  256. package/lib/util/rangeMap.d.ts.map +1 -1
  257. package/lib/util/rangeMap.js +160 -117
  258. package/lib/util/rangeMap.js.map +1 -1
  259. package/lib/util/utils.d.ts +4 -1
  260. package/lib/util/utils.d.ts.map +1 -1
  261. package/lib/util/utils.js +7 -1
  262. package/lib/util/utils.js.map +1 -1
  263. package/package.json +23 -23
  264. package/src/core/index.ts +5 -2
  265. package/src/core/rebase/index.ts +5 -0
  266. package/src/core/rebase/types.ts +33 -5
  267. package/src/core/rebase/utils.ts +27 -0
  268. package/src/core/tree/delta.ts +21 -26
  269. package/src/core/tree/deltaUtil.ts +1 -16
  270. package/src/core/tree/index.ts +0 -2
  271. package/src/core/tree/visitDelta.ts +108 -97
  272. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +2 -2
  273. package/src/feature-libraries/deltaUtils.ts +13 -0
  274. package/src/feature-libraries/forest-summary/forestSummarizer.ts +1 -6
  275. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +12 -13
  276. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +21 -1
  277. package/src/feature-libraries/modular-schema/genericFieldKind.ts +2 -2
  278. package/src/feature-libraries/modular-schema/index.ts +2 -0
  279. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +12 -11
  280. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +138 -225
  281. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +40 -27
  282. package/src/feature-libraries/optional-field/optionalField.ts +3 -3
  283. package/src/feature-libraries/sequence-field/moveEffectTable.ts +1 -1
  284. package/src/feature-libraries/sequence-field/rebase.ts +9 -3
  285. package/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts +1 -1
  286. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +1 -1
  287. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +3 -4
  288. package/src/feature-libraries/sequence-field/utils.ts +36 -4
  289. package/src/feature-libraries/treeCursorUtils.ts +6 -1
  290. package/src/index.ts +34 -6
  291. package/src/packageVersion.ts +1 -1
  292. package/src/shared-tree/index.ts +4 -1
  293. package/src/shared-tree/sharedTree.ts +60 -40
  294. package/src/shared-tree/treeCheckout.ts +19 -12
  295. package/src/simple-tree/api/treeNodeApi.ts +1 -1
  296. package/src/simple-tree/arrayNode.ts +1 -1
  297. package/src/simple-tree/toMapTree.ts +1 -1
  298. package/src/util/bTreeUtils.ts +60 -0
  299. package/src/util/idAllocator.ts +0 -2
  300. package/src/util/index.ts +3 -0
  301. package/src/util/rangeMap.ts +208 -143
  302. package/src/util/utils.ts +10 -3
  303. package/lib/package.json +0 -3
@@ -105,6 +105,8 @@ export function visitDelta(
105
105
  rootDestructions,
106
106
  };
107
107
  processBuilds(delta.build, detachConfig, visitor);
108
+ processGlobal(delta.global, detachConfig, visitor);
109
+ processRename(delta.rename, detachConfig);
108
110
  visitFieldMarks(delta.fields, visitor, detachConfig);
109
111
  fixedPointVisitOfRoots(visitor, detachPassRoots, detachConfig);
110
112
  transferRoots(
@@ -420,52 +422,32 @@ function visitNode(
420
422
  * (because we want to wait until we are sure content to attach is available as a root)
421
423
  */
422
424
  function detachPass(
423
- delta: Delta.FieldChanges,
425
+ fieldChanges: Delta.FieldChanges,
424
426
  visitor: DeltaVisitor,
425
427
  config: PassConfig,
426
428
  ): void {
427
- if (delta.global !== undefined) {
428
- for (const { id, fields } of delta.global) {
429
- let root = config.detachedFieldIndex.tryGetEntry(id);
430
- if (root === undefined) {
431
- const tree = tryGetFromNestedMap(config.refreshers, id.major, id.minor);
432
- assert(tree !== undefined, 0x928 /* refresher data not found */);
433
- buildTrees(id, [tree], config.detachedFieldIndex, config.latestRevision, visitor);
434
- root = config.detachedFieldIndex.getEntry(id);
435
- }
436
- // the revision is updated for any refresher data included in the delta that is used
437
- config.detachedFieldIndex.updateLatestRevision(id, config.latestRevision);
438
- config.detachPassRoots.set(root, fields);
439
- config.attachPassRoots.set(root, fields);
429
+ let index = 0;
430
+ for (const mark of fieldChanges) {
431
+ if (mark.fields !== undefined) {
432
+ assert(
433
+ mark.attach === undefined || mark.detach !== undefined,
434
+ 0x7d0 /* Invalid nested changes on an additive mark */,
435
+ );
436
+ visitNode(index, mark.fields, visitor, config);
440
437
  }
441
- }
442
- if (delta.rename !== undefined) {
443
- config.rootTransfers.push(...delta.rename);
444
- }
445
- if (delta.local !== undefined) {
446
- let index = 0;
447
- for (const mark of delta.local) {
448
- if (mark.fields !== undefined) {
449
- assert(
450
- mark.attach === undefined || mark.detach !== undefined,
451
- 0x7d0 /* Invalid nested changes on an additive mark */,
452
- );
453
- visitNode(index, mark.fields, visitor, config);
454
- }
455
- if (isDetachMark(mark)) {
456
- for (let i = 0; i < mark.count; i += 1) {
457
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
458
- const id = offsetDetachId(mark.detach!, i);
459
- const root = config.detachedFieldIndex.createEntry(id, config.latestRevision);
460
- if (mark.fields !== undefined) {
461
- config.attachPassRoots.set(root, mark.fields);
462
- }
463
- const field = config.detachedFieldIndex.toFieldKey(root);
464
- visitor.detach({ start: index, end: index + 1 }, field);
438
+ if (isDetachMark(mark)) {
439
+ for (let i = 0; i < mark.count; i += 1) {
440
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
441
+ const id = offsetDetachId(mark.detach!, i);
442
+ const root = config.detachedFieldIndex.createEntry(id, config.latestRevision);
443
+ if (mark.fields !== undefined) {
444
+ config.attachPassRoots.set(root, mark.fields);
465
445
  }
466
- } else if (!isAttachMark(mark)) {
467
- index += mark.count;
446
+ const field = config.detachedFieldIndex.toFieldKey(root);
447
+ visitor.detach({ start: index, end: index + 1 }, field);
468
448
  }
449
+ } else if (!isAttachMark(mark)) {
450
+ index += mark.count;
469
451
  }
470
452
  }
471
453
  }
@@ -499,6 +481,37 @@ function processBuilds(
499
481
  }
500
482
  }
501
483
 
484
+ function processGlobal(
485
+ global: readonly Delta.DetachedNodeChanges[] | undefined,
486
+ config: PassConfig,
487
+ visitor: DeltaVisitor,
488
+ ): void {
489
+ if (global !== undefined) {
490
+ for (const { id, fields } of global) {
491
+ let root = config.detachedFieldIndex.tryGetEntry(id);
492
+ if (root === undefined) {
493
+ const tree = tryGetFromNestedMap(config.refreshers, id.major, id.minor);
494
+ assert(tree !== undefined, 0x928 /* refresher data not found */);
495
+ buildTrees(id, [tree], config.detachedFieldIndex, config.latestRevision, visitor);
496
+ root = config.detachedFieldIndex.getEntry(id);
497
+ }
498
+ // the revision is updated for any refresher data included in the delta that is used
499
+ config.detachedFieldIndex.updateLatestRevision(id, config.latestRevision);
500
+ config.detachPassRoots.set(root, fields);
501
+ config.attachPassRoots.set(root, fields);
502
+ }
503
+ }
504
+ }
505
+
506
+ function processRename(
507
+ rename: readonly Delta.DetachedNodeRename[] | undefined,
508
+ config: PassConfig,
509
+ ): void {
510
+ if (rename !== undefined) {
511
+ config.rootTransfers.push(...rename);
512
+ }
513
+ }
514
+
502
515
  function collectDestroys(
503
516
  destroys: readonly Delta.DetachedNodeDestruction[] | undefined,
504
517
  config: PassConfig,
@@ -515,69 +528,67 @@ function collectDestroys(
515
528
  * - Collects detached roots (from replaces) that need an attach pass
516
529
  */
517
530
  function attachPass(
518
- delta: Delta.FieldChanges,
531
+ fieldChanges: Delta.FieldChanges,
519
532
  visitor: DeltaVisitor,
520
533
  config: PassConfig,
521
534
  ): void {
522
- if (delta.local !== undefined) {
523
- let index = 0;
524
- for (const mark of delta.local) {
525
- if (isAttachMark(mark) || isReplaceMark(mark)) {
526
- for (let i = 0; i < mark.count; i += 1) {
527
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
528
- const offsetAttachId = offsetDetachId(mark.attach!, i);
529
- let sourceRoot = config.detachedFieldIndex.tryGetEntry(offsetAttachId);
530
- if (sourceRoot === undefined) {
531
- const tree = tryGetFromNestedMap(
532
- config.refreshers,
533
- offsetAttachId.major,
534
- offsetAttachId.minor,
535
- );
536
- assert(tree !== undefined, 0x92a /* refresher data not found */);
537
- buildTrees(
538
- offsetAttachId,
539
- [tree],
540
- config.detachedFieldIndex,
541
- config.latestRevision,
542
- visitor,
543
- );
544
- sourceRoot = config.detachedFieldIndex.getEntry(offsetAttachId);
545
- }
546
- const sourceField = config.detachedFieldIndex.toFieldKey(sourceRoot);
547
- const offsetIndex = index + i;
548
- if (isReplaceMark(mark)) {
549
- const rootDestination = config.detachedFieldIndex.createEntry(
550
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
551
- offsetDetachId(mark.detach!, i),
552
- config.latestRevision,
553
- );
554
- const destinationField = config.detachedFieldIndex.toFieldKey(rootDestination);
555
- visitor.replace(
556
- sourceField,
557
- { start: offsetIndex, end: offsetIndex + 1 },
558
- destinationField,
559
- );
560
- // We may need to do a second pass on the detached nodes
561
- if (mark.fields !== undefined) {
562
- config.attachPassRoots.set(rootDestination, mark.fields);
563
- }
564
- } else {
565
- // This a simple attach
566
- visitor.attach(sourceField, 1, offsetIndex);
567
- }
568
- config.detachedFieldIndex.deleteEntry(offsetAttachId);
569
- const fields = config.attachPassRoots.get(sourceRoot);
570
- if (fields !== undefined) {
571
- config.attachPassRoots.delete(sourceRoot);
572
- visitNode(offsetIndex, fields, visitor, config);
535
+ let index = 0;
536
+ for (const mark of fieldChanges) {
537
+ if (isAttachMark(mark) || isReplaceMark(mark)) {
538
+ for (let i = 0; i < mark.count; i += 1) {
539
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
540
+ const offsetAttachId = offsetDetachId(mark.attach!, i);
541
+ let sourceRoot = config.detachedFieldIndex.tryGetEntry(offsetAttachId);
542
+ if (sourceRoot === undefined) {
543
+ const tree = tryGetFromNestedMap(
544
+ config.refreshers,
545
+ offsetAttachId.major,
546
+ offsetAttachId.minor,
547
+ );
548
+ assert(tree !== undefined, 0x92a /* refresher data not found */);
549
+ buildTrees(
550
+ offsetAttachId,
551
+ [tree],
552
+ config.detachedFieldIndex,
553
+ config.latestRevision,
554
+ visitor,
555
+ );
556
+ sourceRoot = config.detachedFieldIndex.getEntry(offsetAttachId);
557
+ }
558
+ const sourceField = config.detachedFieldIndex.toFieldKey(sourceRoot);
559
+ const offsetIndex = index + i;
560
+ if (isReplaceMark(mark)) {
561
+ const rootDestination = config.detachedFieldIndex.createEntry(
562
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
563
+ offsetDetachId(mark.detach!, i),
564
+ config.latestRevision,
565
+ );
566
+ const destinationField = config.detachedFieldIndex.toFieldKey(rootDestination);
567
+ visitor.replace(
568
+ sourceField,
569
+ { start: offsetIndex, end: offsetIndex + 1 },
570
+ destinationField,
571
+ );
572
+ // We may need to do a second pass on the detached nodes
573
+ if (mark.fields !== undefined) {
574
+ config.attachPassRoots.set(rootDestination, mark.fields);
573
575
  }
576
+ } else {
577
+ // This a simple attach
578
+ visitor.attach(sourceField, 1, offsetIndex);
579
+ }
580
+ config.detachedFieldIndex.deleteEntry(offsetAttachId);
581
+ const fields = config.attachPassRoots.get(sourceRoot);
582
+ if (fields !== undefined) {
583
+ config.attachPassRoots.delete(sourceRoot);
584
+ visitNode(offsetIndex, fields, visitor, config);
574
585
  }
575
- } else if (!isDetachMark(mark) && mark.fields !== undefined) {
576
- visitNode(index, mark.fields, visitor, config);
577
- }
578
- if (!isDetachMark(mark)) {
579
- index += mark.count;
580
586
  }
587
+ } else if (!isDetachMark(mark) && mark.fields !== undefined) {
588
+ visitNode(index, mark.fields, visitor, config);
589
+ }
590
+ if (!isDetachMark(mark)) {
591
+ index += mark.count;
581
592
  }
582
593
  }
583
594
  }
@@ -6,13 +6,13 @@
6
6
  import {
7
7
  type ChangeAtomId,
8
8
  type DeltaDetachedNodeId,
9
- type DeltaFieldChanges,
10
9
  type FieldKindIdentifier,
11
10
  forbiddenFieldKindIdentifier,
12
11
  Multiplicity,
13
12
  } from "../../core/index.js";
14
13
  import { fail } from "../../util/index.js";
15
14
  import {
15
+ type FieldChangeDelta,
16
16
  type FieldChangeHandler,
17
17
  type FieldEditor,
18
18
  type FieldKindConfiguration,
@@ -43,7 +43,7 @@ export const noChangeHandler: FieldChangeHandler<0> = {
43
43
  }),
44
44
  codecsFactory: () => noChangeCodecFamily,
45
45
  editor: { buildChildChange: (index, change) => fail("Child changes not supported") },
46
- intoDelta: (change, deltaFromChild: ToDelta): DeltaFieldChanges => ({}),
46
+ intoDelta: (change, deltaFromChild: ToDelta): FieldChangeDelta => ({}),
47
47
  relevantRemovedRoots: (change): Iterable<DeltaDetachedNodeId> => [],
48
48
  isEmpty: (change: 0) => true,
49
49
  getNestedChanges: (change: 0) => [],
@@ -39,5 +39,18 @@ export function mapRootChanges<TIn, TOut>(
39
39
  trees: trees.map(func),
40
40
  }));
41
41
  }
42
+ if (root.global !== undefined) {
43
+ out.global = root.global.map(({ id, fields }) => ({
44
+ id,
45
+ fields,
46
+ }));
47
+ }
48
+ if (root.rename !== undefined) {
49
+ out.rename = root.rename.map(({ count, oldId, newId }) => ({
50
+ count,
51
+ oldId,
52
+ newId,
53
+ }));
54
+ }
42
55
  return out;
43
56
  }
@@ -150,12 +150,7 @@ export class ForestSummarizer implements Summarizable {
150
150
  id: buildId,
151
151
  trees: nodeCursors,
152
152
  });
153
- fieldChanges.push([
154
- fieldKey,
155
- {
156
- local: [{ count: nodeCursors.length, attach: buildId }],
157
- },
158
- ]);
153
+ fieldChanges.push([fieldKey, [{ count: nodeCursors.length, attach: buildId }]]);
159
154
  }
160
155
 
161
156
  assert(this.forest.isEmpty, 0x797 /* forest must be empty */);
@@ -3,11 +3,16 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type { ChangesetLocalId, RevisionTag } from "../../core/index.js";
7
- import { RangeMap, type RangeQueryResult } from "../../util/index.js";
6
+ import type {
7
+ ChangeAtomId,
8
+ ChangeAtomIdRangeMap,
9
+ ChangesetLocalId,
10
+ RevisionTag,
11
+ } from "../../core/index.js";
12
+ import type { RangeQueryResult } from "../../util/index.js";
8
13
  import type { NodeId } from "./modularChangeTypes.js";
9
14
 
10
- export type CrossFieldMap<T> = Map<RevisionTag | undefined, RangeMap<T>>;
15
+ export type CrossFieldMap<T> = ChangeAtomIdRangeMap<T>;
11
16
  export type CrossFieldQuerySet = CrossFieldMap<boolean>;
12
17
 
13
18
  export function addCrossFieldQuery(
@@ -26,12 +31,7 @@ export function setInCrossFieldMap<T>(
26
31
  count: number,
27
32
  value: T,
28
33
  ): void {
29
- let rangeMap = map.get(revision);
30
- if (rangeMap === undefined) {
31
- rangeMap = new RangeMap();
32
- map.set(revision, rangeMap);
33
- }
34
- rangeMap.set(id, count, value);
34
+ map.set({ revision, localId: id }, count, value);
35
35
  }
36
36
 
37
37
  export function getFirstFromCrossFieldMap<T>(
@@ -39,9 +39,8 @@ export function getFirstFromCrossFieldMap<T>(
39
39
  revision: RevisionTag | undefined,
40
40
  id: ChangesetLocalId,
41
41
  count: number,
42
- ): RangeQueryResult<T> {
43
- const rangeMap = map.has(revision) ? (map.get(revision) as RangeMap<T>) : new RangeMap<T>();
44
- return rangeMap.get(id, count);
42
+ ): RangeQueryResult<ChangeAtomId, T> {
43
+ return map.getFirst({ revision, localId: id }, count);
45
44
  }
46
45
 
47
46
  /**
@@ -66,7 +65,7 @@ export interface CrossFieldManager<T = unknown> {
66
65
  id: ChangesetLocalId,
67
66
  count: number,
68
67
  addDependency: boolean,
69
- ): RangeQueryResult<T>;
68
+ ): RangeQueryResult<ChangeAtomId, T>;
70
69
 
71
70
  /**
72
71
  * Sets the range of keys to `newValue`.
@@ -6,7 +6,9 @@
6
6
  import type { ICodecFamily, IJsonCodec } from "../../codec/index.js";
7
7
  import type {
8
8
  ChangeEncodingContext,
9
+ DeltaDetachedNodeChanges,
9
10
  DeltaDetachedNodeId,
11
+ DeltaDetachedNodeRename,
10
12
  DeltaFieldChanges,
11
13
  DeltaFieldMap,
12
14
  EncodedRevisionTag,
@@ -25,6 +27,24 @@ export type NestedChangesIndices = [
25
27
  number | undefined /* outputIndex */,
26
28
  ][];
27
29
 
30
+ /**
31
+ * The return value of calling {@link FieldChangeHandler.intoDelta}.
32
+ */
33
+ export interface FieldChangeDelta {
34
+ /**
35
+ * {@inheritdoc DeltaFieldChanges}
36
+ */
37
+ readonly local?: DeltaFieldChanges;
38
+ /**
39
+ * {@inheritdoc DeltaRoot.global}
40
+ */
41
+ readonly global?: readonly DeltaDetachedNodeChanges[];
42
+ /**
43
+ * {@inheritdoc DeltaRoot.rename}
44
+ */
45
+ readonly rename?: readonly DeltaDetachedNodeRename[];
46
+ }
47
+
28
48
  /**
29
49
  * Functionality provided by a field kind which will be composed with other `FieldChangeHandler`s to
30
50
  * implement a unified ChangeFamily supporting documents with multiple field kinds.
@@ -44,7 +64,7 @@ export interface FieldChangeHandler<
44
64
  >,
45
65
  ) => ICodecFamily<TChangeset, FieldChangeEncodingContext>;
46
66
  readonly editor: TEditor;
47
- intoDelta(change: TChangeset, deltaFromChild: ToDelta): DeltaFieldChanges;
67
+ intoDelta(change: TChangeset, deltaFromChild: ToDelta): FieldChangeDelta;
48
68
  /**
49
69
  * Returns the set of removed roots that should be in memory for the given change to be applied.
50
70
  * A removed root is relevant if any of the following is true:
@@ -5,7 +5,6 @@
5
5
 
6
6
  import {
7
7
  type DeltaDetachedNodeId,
8
- type DeltaFieldChanges,
9
8
  type DeltaMark,
10
9
  type RevisionMetadataSource,
11
10
  Multiplicity,
@@ -16,6 +15,7 @@ import { type IdAllocator, fail } from "../../util/index.js";
16
15
  import { assert } from "@fluidframework/core-utils/internal";
17
16
  import type { CrossFieldManager } from "./crossFieldQueries.js";
18
17
  import type {
18
+ FieldChangeDelta,
19
19
  FieldChangeHandler,
20
20
  NestedChangesIndices,
21
21
  NodeChangeComposer,
@@ -47,7 +47,7 @@ export const genericChangeHandler: FieldChangeHandler<GenericChangeset> = {
47
47
  return newGenericChangeset([[index, change]]);
48
48
  },
49
49
  },
50
- intoDelta: (change: GenericChangeset, deltaFromChild: ToDelta): DeltaFieldChanges => {
50
+ intoDelta: (change: GenericChangeset, deltaFromChild: ToDelta): FieldChangeDelta => {
51
51
  let nodeIndex = 0;
52
52
  const markList: DeltaMark[] = [];
53
53
  for (const [index, nodeChange] of change.entries()) {
@@ -29,6 +29,7 @@ export { FlexFieldKind, type FullSchemaPolicy } from "./fieldKind.js";
29
29
  export { FieldKindWithEditor } from "./fieldKindWithEditor.js";
30
30
  export {
31
31
  type FieldChangeHandler,
32
+ type FieldChangeDelta,
32
33
  type FieldChangeRebaser,
33
34
  type FieldEditor,
34
35
  type NodeChangeComposer,
@@ -44,6 +45,7 @@ export {
44
45
  type NestedChangesIndices,
45
46
  } from "./fieldChangeHandler.js";
46
47
  export type {
48
+ CrossFieldKey,
47
49
  CrossFieldKeyRange,
48
50
  FieldChange,
49
51
  FieldChangeMap,
@@ -32,6 +32,7 @@ import {
32
32
  brand,
33
33
  fail,
34
34
  idAllocatorFromMaxId,
35
+ newTupleBTree,
35
36
  } from "../../util/index.js";
36
37
  import {
37
38
  type FieldBatchCodec,
@@ -55,17 +56,17 @@ import {
55
56
  type EncodedNodeChangeset,
56
57
  type EncodedRevisionInfo,
57
58
  } from "./modularChangeFormat.js";
58
- import type {
59
- ChangeAtomIdBTree,
60
- FieldChangeMap,
61
- FieldChangeset,
62
- FieldId,
63
- ModularChangeset,
64
- NodeChangeset,
65
- NodeId,
59
+ import {
60
+ newCrossFieldKeyTable,
61
+ type ChangeAtomIdBTree,
62
+ type FieldChangeMap,
63
+ type FieldChangeset,
64
+ type FieldId,
65
+ type ModularChangeset,
66
+ type NodeChangeset,
67
+ type NodeId,
66
68
  } from "./modularChangeTypes.js";
67
69
  import type { FieldChangeEncodingContext, FieldChangeHandler } from "./fieldChangeHandler.js";
68
- import { newCrossFieldKeyTable, newTupleBTree } from "./modularChangeFamily.js";
69
70
 
70
71
  export function makeModularChangeCodecFamily(
71
72
  fieldKindConfigurations: ReadonlyMap<number, FieldKindConfiguration>,
@@ -276,8 +277,8 @@ function makeModularChangeCodec(
276
277
  fieldChangeset,
277
278
  );
278
279
 
279
- for (const crossFieldKey of crossFieldKeys) {
280
- decoded.crossFieldKeys.set(crossFieldKey, fieldId);
280
+ for (const { key, count } of crossFieldKeys) {
281
+ decoded.crossFieldKeys.set(key, count, fieldId);
281
282
  }
282
283
 
283
284
  const fieldKey: FieldKey = brand<FieldKey>(field.fieldKey);