@fluidframework/tree 2.63.0-358419 → 2.63.0-359286

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 (345) hide show
  1. package/.eslintrc.cjs +4 -0
  2. package/api-report/tree.alpha.api.md +31 -5
  3. package/api-report/tree.beta.api.md +26 -0
  4. package/api-report/tree.legacy.beta.api.md +26 -0
  5. package/dist/alpha.d.ts +4 -3
  6. package/dist/beta.d.ts +3 -0
  7. package/dist/codec/codec.d.ts +32 -0
  8. package/dist/codec/codec.d.ts.map +1 -1
  9. package/dist/codec/codec.js +32 -1
  10. package/dist/codec/codec.js.map +1 -1
  11. package/dist/codec/index.d.ts +1 -1
  12. package/dist/codec/index.d.ts.map +1 -1
  13. package/dist/codec/index.js +3 -1
  14. package/dist/codec/index.js.map +1 -1
  15. package/dist/core/index.d.ts +2 -2
  16. package/dist/core/index.d.ts.map +1 -1
  17. package/dist/core/index.js +4 -3
  18. package/dist/core/index.js.map +1 -1
  19. package/dist/core/schema-stored/index.d.ts +1 -1
  20. package/dist/core/schema-stored/index.d.ts.map +1 -1
  21. package/dist/core/schema-stored/index.js.map +1 -1
  22. package/dist/core/schema-stored/schema.d.ts +5 -7
  23. package/dist/core/schema-stored/schema.d.ts.map +1 -1
  24. package/dist/core/schema-stored/schema.js +3 -6
  25. package/dist/core/schema-stored/schema.js.map +1 -1
  26. package/dist/core/tree/detachedFieldIndexCodecs.d.ts +4 -1
  27. package/dist/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
  28. package/dist/core/tree/detachedFieldIndexCodecs.js +5 -1
  29. package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
  30. package/dist/core/tree/index.d.ts +1 -0
  31. package/dist/core/tree/index.d.ts.map +1 -1
  32. package/dist/core/tree/index.js +3 -1
  33. package/dist/core/tree/index.js.map +1 -1
  34. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +3 -2
  35. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/codec/codecs.js +5 -1
  37. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/codec/format.d.ts +2 -0
  39. package/dist/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  40. package/dist/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  41. package/dist/feature-libraries/chunked-forest/codec/index.d.ts +2 -2
  42. package/dist/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
  43. package/dist/feature-libraries/chunked-forest/codec/index.js +2 -1
  44. package/dist/feature-libraries/chunked-forest/codec/index.js.map +1 -1
  45. package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
  46. package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  47. package/dist/feature-libraries/chunked-forest/index.js +2 -1
  48. package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
  49. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +5 -1
  50. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  51. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +19 -5
  52. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  53. package/dist/feature-libraries/default-schema/index.d.ts +1 -1
  54. package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
  55. package/dist/feature-libraries/default-schema/index.js +2 -1
  56. package/dist/feature-libraries/default-schema/index.js.map +1 -1
  57. package/dist/feature-libraries/forest-summary/codec.d.ts +4 -1
  58. package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  59. package/dist/feature-libraries/forest-summary/codec.js +5 -1
  60. package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
  61. package/dist/feature-libraries/forest-summary/index.d.ts +1 -0
  62. package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
  63. package/dist/feature-libraries/forest-summary/index.js +3 -1
  64. package/dist/feature-libraries/forest-summary/index.js.map +1 -1
  65. package/dist/feature-libraries/index.d.ts +5 -5
  66. package/dist/feature-libraries/index.d.ts.map +1 -1
  67. package/dist/feature-libraries/index.js +7 -2
  68. package/dist/feature-libraries/index.js.map +1 -1
  69. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
  70. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  71. package/dist/feature-libraries/schema-edits/index.d.ts +1 -1
  72. package/dist/feature-libraries/schema-edits/index.d.ts.map +1 -1
  73. package/dist/feature-libraries/schema-edits/index.js +2 -1
  74. package/dist/feature-libraries/schema-edits/index.js.map +1 -1
  75. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.d.ts +4 -1
  76. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
  77. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js +9 -1
  78. package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
  79. package/dist/feature-libraries/schema-index/codec.d.ts +2 -1
  80. package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
  81. package/dist/feature-libraries/schema-index/codec.js +5 -1
  82. package/dist/feature-libraries/schema-index/codec.js.map +1 -1
  83. package/dist/feature-libraries/schema-index/index.d.ts +1 -1
  84. package/dist/feature-libraries/schema-index/index.d.ts.map +1 -1
  85. package/dist/feature-libraries/schema-index/index.js +2 -1
  86. package/dist/feature-libraries/schema-index/index.js.map +1 -1
  87. package/dist/legacy.d.ts +3 -0
  88. package/dist/packageVersion.d.ts +1 -1
  89. package/dist/packageVersion.js +1 -1
  90. package/dist/packageVersion.js.map +1 -1
  91. package/dist/serializableDomainSchema.d.ts +12 -16
  92. package/dist/serializableDomainSchema.d.ts.map +1 -1
  93. package/dist/serializableDomainSchema.js +8 -8
  94. package/dist/serializableDomainSchema.js.map +1 -1
  95. package/dist/shared-tree/index.d.ts +2 -1
  96. package/dist/shared-tree/index.d.ts.map +1 -1
  97. package/dist/shared-tree/index.js +4 -1
  98. package/dist/shared-tree/index.js.map +1 -1
  99. package/dist/shared-tree/sharedTree.d.ts +18 -2
  100. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  101. package/dist/shared-tree/sharedTree.js +122 -8
  102. package/dist/shared-tree/sharedTree.js.map +1 -1
  103. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +17 -2
  104. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  105. package/dist/shared-tree/sharedTreeChangeCodecs.js +31 -18
  106. package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  107. package/dist/shared-tree/treeCheckout.js.map +1 -1
  108. package/dist/shared-tree-core/defaultResubmitMachine.d.ts +7 -12
  109. package/dist/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
  110. package/dist/shared-tree-core/defaultResubmitMachine.js +53 -73
  111. package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  112. package/dist/shared-tree-core/editManagerCodecs.d.ts +7 -4
  113. package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  114. package/dist/shared-tree-core/editManagerCodecs.js +42 -11
  115. package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
  116. package/dist/shared-tree-core/index.d.ts +2 -1
  117. package/dist/shared-tree-core/index.d.ts.map +1 -1
  118. package/dist/shared-tree-core/index.js +6 -1
  119. package/dist/shared-tree-core/index.js.map +1 -1
  120. package/dist/shared-tree-core/messageCodecs.d.ts +7 -4
  121. package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
  122. package/dist/shared-tree-core/messageCodecs.js +44 -23
  123. package/dist/shared-tree-core/messageCodecs.js.map +1 -1
  124. package/dist/shared-tree-core/resubmitMachine.d.ts +9 -18
  125. package/dist/shared-tree-core/resubmitMachine.d.ts.map +1 -1
  126. package/dist/shared-tree-core/resubmitMachine.js.map +1 -1
  127. package/dist/shared-tree-core/sharedTreeCore.d.ts +6 -4
  128. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  129. package/dist/shared-tree-core/sharedTreeCore.js +12 -13
  130. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  131. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +7 -166
  132. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  133. package/dist/simple-tree/api/schemaFactoryAlpha.js +11 -44
  134. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  135. package/dist/simple-tree/api/schemaFactoryBeta.d.ts +90 -1
  136. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  137. package/dist/simple-tree/api/schemaFactoryBeta.js +55 -0
  138. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  139. package/dist/simple-tree/api/treeBeta.d.ts +12 -2
  140. package/dist/simple-tree/api/treeBeta.d.ts.map +1 -1
  141. package/dist/simple-tree/api/treeBeta.js +6 -0
  142. package/dist/simple-tree/api/treeBeta.js.map +1 -1
  143. package/dist/simple-tree/api/typesUnsafe.d.ts +1 -1
  144. package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
  145. package/dist/simple-tree/core/treeNode.d.ts +3 -2
  146. package/dist/simple-tree/core/treeNode.d.ts.map +1 -1
  147. package/dist/simple-tree/core/treeNode.js +3 -2
  148. package/dist/simple-tree/core/treeNode.js.map +1 -1
  149. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  150. package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts +2 -2
  151. package/dist/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
  152. package/dist/util/brand.d.ts +1 -1
  153. package/dist/util/brand.js.map +1 -1
  154. package/docs/main/compatibility.md +8 -0
  155. package/lib/alpha.d.ts +4 -3
  156. package/lib/beta.d.ts +3 -0
  157. package/lib/codec/codec.d.ts +32 -0
  158. package/lib/codec/codec.d.ts.map +1 -1
  159. package/lib/codec/codec.js +28 -0
  160. package/lib/codec/codec.js.map +1 -1
  161. package/lib/codec/index.d.ts +1 -1
  162. package/lib/codec/index.d.ts.map +1 -1
  163. package/lib/codec/index.js +1 -1
  164. package/lib/codec/index.js.map +1 -1
  165. package/lib/core/index.d.ts +2 -2
  166. package/lib/core/index.d.ts.map +1 -1
  167. package/lib/core/index.js +1 -1
  168. package/lib/core/index.js.map +1 -1
  169. package/lib/core/schema-stored/index.d.ts +1 -1
  170. package/lib/core/schema-stored/index.d.ts.map +1 -1
  171. package/lib/core/schema-stored/index.js.map +1 -1
  172. package/lib/core/schema-stored/schema.d.ts +5 -7
  173. package/lib/core/schema-stored/schema.d.ts.map +1 -1
  174. package/lib/core/schema-stored/schema.js +3 -6
  175. package/lib/core/schema-stored/schema.js.map +1 -1
  176. package/lib/core/tree/detachedFieldIndexCodecs.d.ts +4 -1
  177. package/lib/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
  178. package/lib/core/tree/detachedFieldIndexCodecs.js +3 -0
  179. package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
  180. package/lib/core/tree/index.d.ts +1 -0
  181. package/lib/core/tree/index.d.ts.map +1 -1
  182. package/lib/core/tree/index.js +1 -0
  183. package/lib/core/tree/index.js.map +1 -1
  184. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +3 -2
  185. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  186. package/lib/feature-libraries/chunked-forest/codec/codecs.js +3 -0
  187. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  188. package/lib/feature-libraries/chunked-forest/codec/format.d.ts +2 -0
  189. package/lib/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
  190. package/lib/feature-libraries/chunked-forest/codec/format.js.map +1 -1
  191. package/lib/feature-libraries/chunked-forest/codec/index.d.ts +2 -2
  192. package/lib/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
  193. package/lib/feature-libraries/chunked-forest/codec/index.js +1 -1
  194. package/lib/feature-libraries/chunked-forest/codec/index.js.map +1 -1
  195. package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
  196. package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  197. package/lib/feature-libraries/chunked-forest/index.js +1 -1
  198. package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
  199. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +5 -1
  200. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  201. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +17 -4
  202. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  203. package/lib/feature-libraries/default-schema/index.d.ts +1 -1
  204. package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
  205. package/lib/feature-libraries/default-schema/index.js +1 -1
  206. package/lib/feature-libraries/default-schema/index.js.map +1 -1
  207. package/lib/feature-libraries/forest-summary/codec.d.ts +4 -1
  208. package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  209. package/lib/feature-libraries/forest-summary/codec.js +3 -0
  210. package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
  211. package/lib/feature-libraries/forest-summary/index.d.ts +1 -0
  212. package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
  213. package/lib/feature-libraries/forest-summary/index.js +1 -0
  214. package/lib/feature-libraries/forest-summary/index.js.map +1 -1
  215. package/lib/feature-libraries/index.d.ts +5 -5
  216. package/lib/feature-libraries/index.d.ts.map +1 -1
  217. package/lib/feature-libraries/index.js +5 -5
  218. package/lib/feature-libraries/index.js.map +1 -1
  219. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
  220. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  221. package/lib/feature-libraries/schema-edits/index.d.ts +1 -1
  222. package/lib/feature-libraries/schema-edits/index.d.ts.map +1 -1
  223. package/lib/feature-libraries/schema-edits/index.js +1 -1
  224. package/lib/feature-libraries/schema-edits/index.js.map +1 -1
  225. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.d.ts +4 -1
  226. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
  227. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js +8 -1
  228. package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
  229. package/lib/feature-libraries/schema-index/codec.d.ts +2 -1
  230. package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
  231. package/lib/feature-libraries/schema-index/codec.js +3 -0
  232. package/lib/feature-libraries/schema-index/codec.js.map +1 -1
  233. package/lib/feature-libraries/schema-index/index.d.ts +1 -1
  234. package/lib/feature-libraries/schema-index/index.d.ts.map +1 -1
  235. package/lib/feature-libraries/schema-index/index.js +1 -1
  236. package/lib/feature-libraries/schema-index/index.js.map +1 -1
  237. package/lib/legacy.d.ts +3 -0
  238. package/lib/packageVersion.d.ts +1 -1
  239. package/lib/packageVersion.js +1 -1
  240. package/lib/packageVersion.js.map +1 -1
  241. package/lib/serializableDomainSchema.d.ts +12 -16
  242. package/lib/serializableDomainSchema.d.ts.map +1 -1
  243. package/lib/serializableDomainSchema.js +9 -9
  244. package/lib/serializableDomainSchema.js.map +1 -1
  245. package/lib/shared-tree/index.d.ts +2 -1
  246. package/lib/shared-tree/index.d.ts.map +1 -1
  247. package/lib/shared-tree/index.js +2 -1
  248. package/lib/shared-tree/index.js.map +1 -1
  249. package/lib/shared-tree/sharedTree.d.ts +18 -2
  250. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  251. package/lib/shared-tree/sharedTree.js +126 -13
  252. package/lib/shared-tree/sharedTree.js.map +1 -1
  253. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +17 -2
  254. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  255. package/lib/shared-tree/sharedTreeChangeCodecs.js +30 -18
  256. package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  257. package/lib/shared-tree/treeCheckout.js.map +1 -1
  258. package/lib/shared-tree-core/defaultResubmitMachine.d.ts +7 -12
  259. package/lib/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
  260. package/lib/shared-tree-core/defaultResubmitMachine.js +55 -75
  261. package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  262. package/lib/shared-tree-core/editManagerCodecs.d.ts +7 -4
  263. package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  264. package/lib/shared-tree-core/editManagerCodecs.js +40 -10
  265. package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
  266. package/lib/shared-tree-core/index.d.ts +2 -1
  267. package/lib/shared-tree-core/index.d.ts.map +1 -1
  268. package/lib/shared-tree-core/index.js +2 -1
  269. package/lib/shared-tree-core/index.js.map +1 -1
  270. package/lib/shared-tree-core/messageCodecs.d.ts +7 -4
  271. package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
  272. package/lib/shared-tree-core/messageCodecs.js +42 -22
  273. package/lib/shared-tree-core/messageCodecs.js.map +1 -1
  274. package/lib/shared-tree-core/resubmitMachine.d.ts +9 -18
  275. package/lib/shared-tree-core/resubmitMachine.d.ts.map +1 -1
  276. package/lib/shared-tree-core/resubmitMachine.js.map +1 -1
  277. package/lib/shared-tree-core/sharedTreeCore.d.ts +6 -4
  278. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  279. package/lib/shared-tree-core/sharedTreeCore.js +13 -14
  280. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  281. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +7 -166
  282. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  283. package/lib/simple-tree/api/schemaFactoryAlpha.js +12 -45
  284. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  285. package/lib/simple-tree/api/schemaFactoryBeta.d.ts +90 -1
  286. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  287. package/lib/simple-tree/api/schemaFactoryBeta.js +56 -1
  288. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  289. package/lib/simple-tree/api/treeBeta.d.ts +12 -2
  290. package/lib/simple-tree/api/treeBeta.d.ts.map +1 -1
  291. package/lib/simple-tree/api/treeBeta.js +7 -1
  292. package/lib/simple-tree/api/treeBeta.js.map +1 -1
  293. package/lib/simple-tree/api/typesUnsafe.d.ts +1 -1
  294. package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
  295. package/lib/simple-tree/core/treeNode.d.ts +3 -2
  296. package/lib/simple-tree/core/treeNode.d.ts.map +1 -1
  297. package/lib/simple-tree/core/treeNode.js +3 -2
  298. package/lib/simple-tree/core/treeNode.js.map +1 -1
  299. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  300. package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts +2 -2
  301. package/lib/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
  302. package/lib/util/brand.d.ts +1 -1
  303. package/lib/util/brand.js.map +1 -1
  304. package/package.json +21 -21
  305. package/src/codec/codec.ts +60 -0
  306. package/src/codec/index.ts +3 -0
  307. package/src/core/index.ts +3 -0
  308. package/src/core/schema-stored/index.ts +1 -0
  309. package/src/core/schema-stored/schema.ts +5 -6
  310. package/src/core/tree/detachedFieldIndexCodecs.ts +9 -0
  311. package/src/core/tree/index.ts +6 -0
  312. package/src/feature-libraries/chunked-forest/codec/codecs.ts +6 -1
  313. package/src/feature-libraries/chunked-forest/codec/format.ts +2 -0
  314. package/src/feature-libraries/chunked-forest/codec/index.ts +2 -1
  315. package/src/feature-libraries/chunked-forest/index.ts +2 -0
  316. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +29 -5
  317. package/src/feature-libraries/default-schema/index.ts +2 -0
  318. package/src/feature-libraries/forest-summary/codec.ts +7 -0
  319. package/src/feature-libraries/forest-summary/index.ts +1 -0
  320. package/src/feature-libraries/index.ts +12 -1
  321. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1 -1
  322. package/src/feature-libraries/schema-edits/index.ts +5 -1
  323. package/src/feature-libraries/schema-edits/schemaChangeCodecs.ts +17 -1
  324. package/src/feature-libraries/schema-index/codec.ts +5 -0
  325. package/src/feature-libraries/schema-index/index.ts +1 -0
  326. package/src/packageVersion.ts +1 -1
  327. package/src/serializableDomainSchema.ts +12 -11
  328. package/src/shared-tree/index.ts +6 -0
  329. package/src/shared-tree/sharedTree.ts +151 -11
  330. package/src/shared-tree/sharedTreeChangeCodecs.ts +68 -30
  331. package/src/shared-tree/treeCheckout.ts +1 -1
  332. package/src/shared-tree-core/defaultResubmitMachine.ts +77 -120
  333. package/src/shared-tree-core/editManagerCodecs.ts +62 -9
  334. package/src/shared-tree-core/index.ts +12 -1
  335. package/src/shared-tree-core/messageCodecs.ts +70 -27
  336. package/src/shared-tree-core/resubmitMachine.ts +12 -20
  337. package/src/shared-tree-core/sharedTreeCore.ts +26 -18
  338. package/src/simple-tree/api/schemaFactoryAlpha.ts +16 -296
  339. package/src/simple-tree/api/schemaFactoryBeta.ts +269 -1
  340. package/src/simple-tree/api/treeBeta.ts +36 -1
  341. package/src/simple-tree/api/typesUnsafe.ts +1 -1
  342. package/src/simple-tree/core/treeNode.ts +3 -2
  343. package/src/simple-tree/core/treeNodeKernel.ts +1 -1
  344. package/src/simple-tree/node-kinds/record/recordNodeTypes.ts +2 -2
  345. package/src/util/brand.ts +1 -1
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { ErasedType, IFluidLoadable } from "@fluidframework/core-interfaces/internal";
7
- import { assert, fail } from "@fluidframework/core-utils/internal";
7
+ import { assert, fail, unreachableCase } from "@fluidframework/core-utils/internal";
8
8
  import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
9
9
  import type { IIdCompressor, StableId } from "@fluidframework/id-compressor";
10
10
  import type {
@@ -18,12 +18,15 @@ import {
18
18
  } from "@fluidframework/telemetry-utils/internal";
19
19
 
20
20
  import {
21
+ type CodecTree,
21
22
  type CodecWriteOptions,
23
+ DependentFormatVersion,
22
24
  FluidClientVersion,
23
25
  FormatValidatorNoOp,
24
26
  type ICodecOptions,
25
27
  } from "../codec/index.js";
26
28
  import {
29
+ type DetachedFieldIndexFormatVersion,
27
30
  type FieldKey,
28
31
  type GraphCommit,
29
32
  type IEditableForest,
@@ -32,6 +35,7 @@ import {
32
35
  MapNodeStoredSchema,
33
36
  ObjectNodeStoredSchema,
34
37
  RevisionTagCodec,
38
+ type SchemaFormatVersion,
35
39
  SchemaVersion,
36
40
  type TreeFieldStoredSchema,
37
41
  type TreeNodeSchemaIdentifier,
@@ -39,6 +43,7 @@ import {
39
43
  type TreeStoredSchema,
40
44
  TreeStoredSchemaRepository,
41
45
  type TreeStoredSchemaSubscription,
46
+ getCodecTreeForDetachedFieldIndexFormat,
42
47
  makeDetachedFieldIndex,
43
48
  moveToDetachedField,
44
49
  } from "../core/index.js";
@@ -51,11 +56,16 @@ import {
51
56
  buildChunkedForest,
52
57
  buildForest,
53
58
  defaultSchemaPolicy,
59
+ getCodecTreeForFieldBatchFormat,
60
+ getCodecTreeForForestFormat,
61
+ getCodecTreeForSchemaFormat,
54
62
  jsonableTreeFromFieldCursor,
55
63
  makeFieldBatchCodec,
56
64
  makeMitigatedChangeFamily,
57
65
  makeSchemaCodec,
58
66
  makeTreeChunker,
67
+ type FieldBatchFormatVersion,
68
+ type ForestFormatVersion,
59
69
  type TreeCompressionStrategyPrivate,
60
70
  } from "../feature-libraries/index.js";
61
71
  // eslint-disable-next-line import/no-internal-modules
@@ -63,7 +73,11 @@ import type { FormatV1 } from "../feature-libraries/schema-index/index.js";
63
73
  import {
64
74
  type BranchId,
65
75
  type ClonableSchemaAndPolicy,
76
+ type EditManagerFormatVersion,
66
77
  type ExplicitCoreCodecVersions,
78
+ getCodecTreeForEditManagerFormatWithChange,
79
+ getCodecTreeForMessageFormatWithChange,
80
+ type MessageFormatVersion,
67
81
  SharedTreeCore,
68
82
  } from "../shared-tree-core/index.js";
69
83
  import {
@@ -92,11 +106,16 @@ import type { SharedTreeChange } from "./sharedTreeChangeTypes.js";
92
106
  import type { SharedTreeEditBuilder } from "./sharedTreeEditBuilder.js";
93
107
  import { type TreeCheckout, type BranchableTree, createTreeCheckout } from "./treeCheckout.js";
94
108
  import {
109
+ brand,
95
110
  type Breakable,
96
111
  breakingClass,
97
112
  type JsonCompatible,
98
113
  throwIfBroken,
99
114
  } from "../util/index.js";
115
+ import {
116
+ getCodecTreeForChangeFormat,
117
+ type SharedTreeChangeFormatVersion,
118
+ } from "./sharedTreeChangeCodecs.js";
100
119
 
101
120
  /**
102
121
  * Copy of data from an {@link ITreePrivate} at some point in time.
@@ -161,36 +180,78 @@ export interface ITreePrivate extends ITreeInternal {
161
180
  * TODO: Plumb these write versions into forest, schema, detached field index codec creation.
162
181
  */
163
182
  interface ExplicitCodecVersions extends ExplicitCoreCodecVersions {
164
- forest: number;
165
- schema: SchemaVersion;
166
- detachedFieldIndex: number;
167
- fieldBatch: number;
183
+ forest: ForestFormatVersion;
184
+ schema: SchemaFormatVersion;
185
+ detachedFieldIndex: DetachedFieldIndexFormatVersion;
186
+ fieldBatch: FieldBatchFormatVersion;
168
187
  }
169
188
 
170
189
  const formatVersionToTopLevelCodecVersions = new Map<number, ExplicitCodecVersions>([
171
190
  [
172
191
  1,
173
- { forest: 1, schema: 1, detachedFieldIndex: 1, editManager: 1, message: 1, fieldBatch: 1 },
192
+ {
193
+ forest: brand(1),
194
+ schema: brand(1),
195
+ detachedFieldIndex: brand(1),
196
+ editManager: brand(1),
197
+ message: brand(1),
198
+ fieldBatch: brand(1),
199
+ },
174
200
  ],
175
201
  [
176
202
  2,
177
- { forest: 1, schema: 1, detachedFieldIndex: 1, editManager: 2, message: 2, fieldBatch: 1 },
203
+ {
204
+ forest: brand(1),
205
+ schema: brand(1),
206
+ detachedFieldIndex: brand(1),
207
+ editManager: brand(2),
208
+ message: brand(2),
209
+ fieldBatch: brand(1),
210
+ },
178
211
  ],
179
212
  [
180
213
  3,
181
- { forest: 1, schema: 1, detachedFieldIndex: 1, editManager: 3, message: 3, fieldBatch: 1 },
214
+ {
215
+ forest: brand(1),
216
+ schema: brand(1),
217
+ detachedFieldIndex: brand(1),
218
+ editManager: brand(3),
219
+ message: brand(3),
220
+ fieldBatch: brand(1),
221
+ },
182
222
  ],
183
223
  [
184
224
  4,
185
- { forest: 1, schema: 1, detachedFieldIndex: 1, editManager: 4, message: 4, fieldBatch: 1 },
225
+ {
226
+ forest: brand(1),
227
+ schema: brand(1),
228
+ detachedFieldIndex: brand(1),
229
+ editManager: brand(4),
230
+ message: brand(4),
231
+ fieldBatch: brand(1),
232
+ },
186
233
  ],
187
234
  [
188
235
  5,
189
- { forest: 1, schema: 2, detachedFieldIndex: 1, editManager: 4, message: 4, fieldBatch: 1 },
236
+ {
237
+ forest: brand(1),
238
+ schema: brand(2),
239
+ detachedFieldIndex: brand(1),
240
+ editManager: brand(4),
241
+ message: brand(4),
242
+ fieldBatch: brand(1),
243
+ },
190
244
  ],
191
245
  [
192
246
  100, // SharedTreeFormatVersion.vSharedBranches
193
- { forest: 1, schema: 2, detachedFieldIndex: 1, editManager: 5, message: 5, fieldBatch: 1 },
247
+ {
248
+ forest: brand(1),
249
+ schema: brand(2),
250
+ detachedFieldIndex: brand(1),
251
+ editManager: brand(5),
252
+ message: brand(5),
253
+ fieldBatch: brand(1),
254
+ },
194
255
  ],
195
256
  ]);
196
257
 
@@ -321,6 +382,8 @@ export class SharedTreeKernel
321
382
  changeFamily,
322
383
  options,
323
384
  codecVersions,
385
+ changeFormatVersionForEditManager,
386
+ changeFormatVersionForMessage,
324
387
  idCompressor,
325
388
  schema,
326
389
  defaultSchemaPolicy,
@@ -635,6 +698,83 @@ export const SharedTreeFormatVersion = {
635
698
  */
636
699
  export type SharedTreeFormatVersion = typeof SharedTreeFormatVersion;
637
700
 
701
+ /**
702
+ * Defines for each EditManagerFormatVersion the SharedTreeChangeFormatVersion to use.
703
+ * This is an arbitrary mapping that is injected in the EditManger codec.
704
+ * Once an entry is defined and used in production, it cannot be changed.
705
+ * This is because the format for SharedTree changes are not explicitly versioned.
706
+ */
707
+ export const changeFormatVersionForEditManager = DependentFormatVersion.fromPairs([
708
+ [brand<EditManagerFormatVersion>(1), brand<SharedTreeChangeFormatVersion>(1)],
709
+ [brand<EditManagerFormatVersion>(2), brand<SharedTreeChangeFormatVersion>(2)],
710
+ [brand<EditManagerFormatVersion>(3), brand<SharedTreeChangeFormatVersion>(3)],
711
+ [brand<EditManagerFormatVersion>(4), brand<SharedTreeChangeFormatVersion>(4)],
712
+ [brand<EditManagerFormatVersion>(5), brand<SharedTreeChangeFormatVersion>(4)],
713
+ ]);
714
+
715
+ /**
716
+ * Defines for each MessageFormatVersion the SharedTreeChangeFormatVersion to use.
717
+ * This is an arbitrary mapping that is injected in the message codec.
718
+ * Once an entry is defined and used in production, it cannot be changed.
719
+ * This is because the format for SharedTree changes are not explicitly versioned.
720
+ */
721
+ export const changeFormatVersionForMessage = DependentFormatVersion.fromPairs([
722
+ [brand<MessageFormatVersion>(undefined), brand<SharedTreeChangeFormatVersion>(1)],
723
+ [brand<MessageFormatVersion>(1), brand<SharedTreeChangeFormatVersion>(1)],
724
+ [brand<MessageFormatVersion>(2), brand<SharedTreeChangeFormatVersion>(2)],
725
+ [brand<MessageFormatVersion>(3), brand<SharedTreeChangeFormatVersion>(3)],
726
+ [brand<MessageFormatVersion>(4), brand<SharedTreeChangeFormatVersion>(4)],
727
+ [brand<MessageFormatVersion>(5), brand<SharedTreeChangeFormatVersion>(4)],
728
+ ]);
729
+
730
+ function getCodecTreeForEditManagerFormat(version: EditManagerFormatVersion): CodecTree {
731
+ const change = changeFormatVersionForEditManager.lookup(version);
732
+ const changeCodecTree = getCodecTreeForChangeFormat(change);
733
+ return getCodecTreeForEditManagerFormatWithChange(version, changeCodecTree);
734
+ }
735
+
736
+ function getCodecTreeForMessageFormat(version: MessageFormatVersion): CodecTree {
737
+ const change = changeFormatVersionForMessage.lookup(version);
738
+ const changeCodecTree = getCodecTreeForChangeFormat(change);
739
+ return getCodecTreeForMessageFormatWithChange(version, changeCodecTree);
740
+ }
741
+
742
+ export function getCodecTreeForSharedTreeFormat(
743
+ version: SharedTreeFormatVersion[keyof SharedTreeFormatVersion],
744
+ ): CodecTree {
745
+ const children: CodecTree[] = [];
746
+ const childCodecs = getCodecVersions(version);
747
+ for (const name of Object.keys(childCodecs) as (keyof ExplicitCodecVersions)[]) {
748
+ switch (name) {
749
+ case "editManager":
750
+ children.push(getCodecTreeForEditManagerFormat(childCodecs.editManager));
751
+ break;
752
+ case "message":
753
+ children.push(getCodecTreeForMessageFormat(childCodecs.message));
754
+ break;
755
+ case "forest":
756
+ children.push(getCodecTreeForForestFormat(childCodecs.forest));
757
+ break;
758
+ case "schema":
759
+ children.push(getCodecTreeForSchemaFormat(childCodecs.schema));
760
+ break;
761
+ case "detachedFieldIndex":
762
+ children.push(getCodecTreeForDetachedFieldIndexFormat(childCodecs.detachedFieldIndex));
763
+ break;
764
+ case "fieldBatch":
765
+ children.push(getCodecTreeForFieldBatchFormat(childCodecs.fieldBatch));
766
+ break;
767
+ default:
768
+ unreachableCase(name);
769
+ }
770
+ }
771
+ return {
772
+ name: "SharedTree",
773
+ version,
774
+ children,
775
+ };
776
+ }
777
+
638
778
  /**
639
779
  * Configuration options for SharedTree.
640
780
  * @beta @input
@@ -3,8 +3,11 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { fail } from "@fluidframework/core-utils/internal";
6
7
  import {
8
+ type CodecTree,
7
9
  DiscriminatedUnionDispatcher,
10
+ type FormatVersion,
8
11
  type ICodecFamily,
9
12
  type ICodecOptions,
10
13
  type IJsonCodec,
@@ -13,12 +16,21 @@ import {
13
16
  } from "../codec/index.js";
14
17
  import type { ChangeEncodingContext, TreeStoredSchema } from "../core/index.js";
15
18
  import {
19
+ type ModularChangeFormatVersion,
16
20
  type ModularChangeset,
17
21
  type SchemaChange,
22
+ type SchemaChangeFormatVersion,
18
23
  defaultSchemaPolicy,
24
+ getCodecTreeForModularChangeFormat,
25
+ getCodecTreeForSchemaChangeFormat,
19
26
  makeSchemaChangeCodecs,
20
27
  } from "../feature-libraries/index.js";
21
- import type { JsonCompatibleReadOnly, Mutable } from "../util/index.js";
28
+ import {
29
+ brand,
30
+ type Brand,
31
+ type JsonCompatibleReadOnly,
32
+ type Mutable,
33
+ } from "../util/index.js";
22
34
 
23
35
  import {
24
36
  EncodedSharedTreeChange,
@@ -31,40 +43,66 @@ export function makeSharedTreeChangeCodecFamily(
31
43
  options: ICodecOptions,
32
44
  ): ICodecFamily<SharedTreeChange, ChangeEncodingContext> {
33
45
  const schemaChangeCodecs = makeSchemaChangeCodecs(options);
34
- return makeCodecFamily([
35
- [
36
- 1,
37
- makeSharedTreeChangeCodec(
38
- modularChangeCodecFamily.resolve(1).json,
39
- schemaChangeCodecs.resolve(1).json,
40
- options,
41
- ),
42
- ],
43
- [
44
- 2,
46
+ const versions: [
47
+ FormatVersion,
48
+ IJsonCodec<
49
+ SharedTreeChange,
50
+ EncodedSharedTreeChange,
51
+ EncodedSharedTreeChange,
52
+ ChangeEncodingContext
53
+ >,
54
+ ][] = Array.from(dependenciesForChangeFormat.entries()).map(
55
+ ([format, { modularChange, schemaChange }]) => [
56
+ format,
45
57
  makeSharedTreeChangeCodec(
46
- modularChangeCodecFamily.resolve(2).json,
47
- schemaChangeCodecs.resolve(1).json,
58
+ modularChangeCodecFamily.resolve(modularChange).json,
59
+ schemaChangeCodecs.resolve(schemaChange).json,
48
60
  options,
49
61
  ),
50
62
  ],
51
- [
52
- 3,
53
- makeSharedTreeChangeCodec(
54
- modularChangeCodecFamily.resolve(3).json,
55
- schemaChangeCodecs.resolve(1).json,
56
- options,
57
- ),
58
- ],
59
- [
60
- 4,
61
- makeSharedTreeChangeCodec(
62
- modularChangeCodecFamily.resolve(4).json,
63
- schemaChangeCodecs.resolve(1).json,
64
- options,
65
- ),
63
+ );
64
+ return makeCodecFamily(versions);
65
+ }
66
+
67
+ interface ChangeFormatDependencies {
68
+ readonly modularChange: ModularChangeFormatVersion;
69
+ readonly schemaChange: SchemaChangeFormatVersion;
70
+ }
71
+
72
+ export type SharedTreeChangeFormatVersion = Brand<
73
+ 1 | 2 | 3 | 4,
74
+ "SharedTreeChangeFormatVersion"
75
+ >;
76
+
77
+ /**
78
+ * Defines for each SharedTree change format the corresponding dependent formats to use.
79
+ * This is an arbitrary mapping that is injected in the SharedTree change codec.
80
+ * Once an entry is defined and used in production, it cannot be changed.
81
+ * This is because the format for the dependent formats are not explicitly versioned.
82
+ */
83
+ export const dependenciesForChangeFormat: Map<
84
+ SharedTreeChangeFormatVersion,
85
+ ChangeFormatDependencies
86
+ > = new Map([
87
+ [brand(1), { modularChange: brand(1), schemaChange: brand(1) }],
88
+ [brand(2), { modularChange: brand(2), schemaChange: brand(1) }],
89
+ [brand(3), { modularChange: brand(3), schemaChange: brand(1) }],
90
+ [brand(4), { modularChange: brand(4), schemaChange: brand(1) }],
91
+ ]);
92
+
93
+ export function getCodecTreeForChangeFormat(
94
+ version: SharedTreeChangeFormatVersion,
95
+ ): CodecTree {
96
+ const { modularChange, schemaChange } =
97
+ dependenciesForChangeFormat.get(version) ?? fail("Unknown change format");
98
+ return {
99
+ name: "SharedTreeChange",
100
+ version,
101
+ children: [
102
+ getCodecTreeForModularChangeFormat(modularChange),
103
+ getCodecTreeForSchemaChangeFormat(schemaChange),
66
104
  ],
67
- ]);
105
+ };
68
106
  }
69
107
 
70
108
  function makeSharedTreeChangeCodec(
@@ -1024,7 +1024,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
1024
1024
  // #region Commit Validation
1025
1025
 
1026
1026
  /** Used to maintain the contract of {@link onCommitValid}(). */
1027
- #validatedCommits = new WeakMap<
1027
+ readonly #validatedCommits = new WeakMap<
1028
1028
  GraphCommit<SharedTreeChange>,
1029
1029
  ((commit: GraphCommit<SharedTreeChange>) => void)[] | true
1030
1030
  >();
@@ -3,16 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import {
7
- assert,
8
- DoublyLinkedList,
9
- oob,
10
- type ListNode,
11
- type ListNodeRange,
12
- } from "@fluidframework/core-utils/internal";
6
+ import { assert, fail, oob } from "@fluidframework/core-utils/internal";
13
7
 
14
- import type { GraphCommit, TaggedChange } from "../core/index.js";
15
- import { disposeSymbol, hasSome } from "../util/index.js";
8
+ import type { GraphCommit, RevisionTag, TaggedChange } from "../core/index.js";
9
+ import { disposeSymbol } from "../util/index.js";
16
10
 
17
11
  import type { ChangeEnricherReadonlyCheckout } from "./changeEnricher.js";
18
12
  import type { ResubmitMachine } from "./resubmitMachine.js";
@@ -21,23 +15,15 @@ interface PendingChange<TChange> {
21
15
  commit: GraphCommit<TChange>;
22
16
  lastEnrichment: number;
23
17
  }
24
- type PendingChangeNode<TChange> = ListNode<PendingChange<TChange>>;
25
18
 
26
19
  /**
27
20
  * Default implementation of {@link ResubmitMachine}.
28
21
  */
29
22
  export class DefaultResubmitMachine<TChange> implements ResubmitMachine<TChange> {
30
23
  /**
31
- * The list of commits (from oldest to most recent) that have been submitted but not sequenced.
24
+ * Maps from revision of submitted commit to the pending change for that commit.
32
25
  */
33
- private readonly inFlightQueue: DoublyLinkedList<PendingChange<TChange>> =
34
- new DoublyLinkedList();
35
-
36
- /**
37
- * The range of in-flight commits that are currently being resubmitted.
38
- * Defined only during the resubmit phase.
39
- */
40
- private pendingResubmitRange: ListNodeRange<PendingChange<TChange>> | undefined;
26
+ private readonly pendingChanges: Map<RevisionTag, PendingChange<TChange>> = new Map();
41
27
 
42
28
  /**
43
29
  * The current enrichment version for in-flight commits.
@@ -58,130 +44,101 @@ export class DefaultResubmitMachine<TChange> implements ResubmitMachine<TChange>
58
44
  ) {}
59
45
 
60
46
  public onCommitSubmitted(commit: GraphCommit<TChange>): void {
61
- if (this.pendingResubmitRange !== undefined) {
62
- const toResubmit = this.pendingResubmitRange?.first;
63
- assert(
64
- toResubmit?.data.commit === commit,
65
- 0x981 /* Unexpected commit submitted during resubmit phase */,
66
- );
67
- // If we are not at the last commit to resubmit, advance the range to the next node.
68
- // Otherwise, clear the resubmit range as we are done resubmitting.
69
- if (toResubmit !== this.pendingResubmitRange.last) {
70
- assert(toResubmit.next !== undefined, 0xbd6 /* must be more in the list */);
71
- this.pendingResubmitRange.first = toResubmit.next;
72
- } else {
73
- this.pendingResubmitRange = undefined;
74
- }
75
- toResubmit.remove();
76
- }
77
- this.inFlightQueue.push({ commit, lastEnrichment: this.currentEnrichment });
47
+ this.pendingChanges.set(commit.revision, {
48
+ commit,
49
+ lastEnrichment: this.currentEnrichment,
50
+ });
78
51
  }
79
52
 
80
53
  public onCommitRollback(commit: GraphCommit<TChange>): void {
81
- assert(
82
- commit.revision === this.inFlightQueue.last?.data.commit.revision,
83
- 0xbd7 /* must rollback latest commit in the in flight queue */,
84
- );
85
- this.inFlightQueue.pop();
54
+ this.pendingChanges.delete(commit.revision);
86
55
  }
87
56
 
88
- public prepareForResubmit(toResubmit: readonly GraphCommit<TChange>[]): void {
89
- assert(
90
- !this.isInResubmitPhase,
91
- 0x957 /* Invalid resubmit phase start during incomplete resubmit phase */,
92
- );
93
-
94
- if (!hasSome(toResubmit)) {
57
+ private updateEnrichments(
58
+ revision: RevisionTag,
59
+ getLocalCommits: () => readonly GraphCommit<TChange>[],
60
+ ): void {
61
+ const pendingChange = this.pendingChanges.get(revision);
62
+ if (
63
+ pendingChange === undefined ||
64
+ pendingChange.lastEnrichment === this.currentEnrichment
65
+ ) {
66
+ // The first commit to resubmit has a valid enrichment, so all pending commits must be valid.
95
67
  return;
96
68
  }
97
69
 
70
+ const localCommits = getLocalCommits();
98
71
  assert(
99
- toResubmit.length <= this.inFlightQueue.length,
100
- 0xbd8 /* Unexpected resubmit of more commits than are in flight */,
72
+ localCommits[0]?.revision === revision,
73
+ "Expected local commits to start with specified revision",
101
74
  );
102
75
 
103
- // Find the first in-flight commit to resubmit.
104
- const first = this.inFlightQueue.find(
105
- (v) => v.data.commit.revision === toResubmit[0].revision,
106
- );
107
- // Always resubmit to the end of all outstanding ops, but the list may grow during resubmit,
108
- // so we must track the current end at the start of the phase.
109
- const last = this.inFlightQueue.last;
110
- assert(
111
- first !== undefined && last !== undefined,
112
- 0xbd9 /* there must be inflight commits to resubmit */,
113
- );
76
+ // Some in-flight commits have stale enrichments, so we recompute them.
77
+ const checkout = this.tip.fork();
78
+
79
+ // Roll back the checkout to the state before the oldest commit
80
+ for (let iCommit = localCommits.length - 1; iCommit >= 0; iCommit -= 1) {
81
+ const commit = localCommits[iCommit] ?? oob();
82
+ const rollback = this.makeRollback(commit);
83
+ // WARNING: it's not currently possible to roll back past a schema change (see AB#7265).
84
+ // Either we have to make it possible to do so, or this logic will have to change to work
85
+ // forwards from an earlier fork instead of backwards.
86
+ checkout.applyTipChange(rollback);
87
+ }
114
88
 
115
- this.pendingResubmitRange = { first, last };
116
- // If any in-flight commits have stale enrichments, recompute them.
117
- if (first.data.lastEnrichment < this.currentEnrichment) {
118
- const checkout = this.tip.fork();
119
-
120
- // Roll back the checkout to the state before the oldest commit
121
- for (let iCommit = toResubmit.length - 1; iCommit >= 0; iCommit -= 1) {
122
- const commit = toResubmit[iCommit] ?? oob();
123
- const rollback = this.makeRollback(commit);
124
- // WARNING: it's not currently possible to roll back past a schema change (see AB#7265).
125
- // Either we have to make it possible to do so, or this logic will have to change to work
126
- // forwards from an earlier fork instead of backwards.
127
- checkout.applyTipChange(rollback);
128
- }
89
+ // Update the enrichments of the stale commits.
90
+ for (const [iCommit, commit] of localCommits.entries()) {
91
+ const current = this.getPendingChange(commit.revision);
92
+ assert(
93
+ current !== undefined,
94
+ 0xbda /* there must be an inflight commit for each resubmit commit */,
95
+ );
129
96
 
130
- // Update the enrichments of the stale commits in the in-flight queue.
131
- let current: PendingChangeNode<TChange> | undefined = first;
132
- for (const commit of toResubmit) {
133
- assert(
134
- current !== undefined,
135
- 0xbda /* there must be an inflight commit for each resubmit commit */,
97
+ if (current.lastEnrichment < this.currentEnrichment) {
98
+ const enrichedChange = checkout.updateChangeEnrichments(
99
+ commit.change,
100
+ commit.revision,
136
101
  );
137
- current.data.commit = commit;
138
- if (current.data.lastEnrichment < this.currentEnrichment) {
139
- const enrichedChange = checkout.updateChangeEnrichments(
140
- commit.change,
141
- commit.revision,
142
- );
143
- const enrichedCommit = { ...commit, change: enrichedChange };
144
-
145
- // Optimization: only apply the enriched change if the next commit also needs enrichment.
146
- if (
147
- current.next !== undefined &&
148
- current.next.data.lastEnrichment < this.currentEnrichment
149
- ) {
150
- checkout.applyTipChange(enrichedChange, commit.revision);
151
- }
152
-
153
- current.data.commit = enrichedCommit;
154
- current.data.lastEnrichment = this.currentEnrichment;
102
+ const enrichedCommit = { ...commit, change: enrichedChange };
103
+
104
+ // Optimization: only apply the enriched change if the next commit also needs enrichment.
105
+ const nextCommit = localCommits[iCommit + 1];
106
+ if (
107
+ nextCommit !== undefined &&
108
+ this.getPendingChange(nextCommit.revision).lastEnrichment < this.currentEnrichment
109
+ ) {
110
+ checkout.applyTipChange(enrichedChange, commit.revision);
155
111
  }
156
- current = current.next;
112
+
113
+ current.commit = enrichedCommit;
114
+ current.lastEnrichment = this.currentEnrichment;
157
115
  }
158
- checkout[disposeSymbol]();
159
116
  }
117
+ checkout[disposeSymbol]();
160
118
  }
161
119
 
162
- public peekNextCommit(): GraphCommit<TChange> {
163
- assert(
164
- this.isInResubmitPhase,
165
- 0x982 /* No available commit to resubmit outside of resubmit phase */,
166
- );
167
- assert(
168
- this.pendingResubmitRange !== undefined,
169
- 0xa87 /* Expected resubmit queue to be non-empty */,
170
- );
171
- return this.pendingResubmitRange.first.data.commit;
120
+ public getEnrichedCommit(
121
+ revision: RevisionTag,
122
+ getLocalCommitsSince: () => readonly GraphCommit<TChange>[],
123
+ ): GraphCommit<TChange> | undefined {
124
+ this.updateEnrichments(revision, getLocalCommitsSince);
125
+ const pendingChange = this.pendingChanges.get(revision);
126
+ return pendingChange?.commit;
172
127
  }
173
128
 
174
- public get isInResubmitPhase(): boolean {
175
- return this.pendingResubmitRange !== undefined;
129
+ private getPendingChange(revision: RevisionTag): PendingChange<TChange> {
130
+ return (
131
+ this.pendingChanges.get(revision) ?? fail("No pending change stored for this revision")
132
+ );
176
133
  }
177
134
 
178
- public onSequencedCommitApplied(isLocal: boolean): void {
179
- if (isLocal) {
180
- // The oldest in-flight commit has been sequenced
181
- assert(this.inFlightQueue.length > 0, 0x959 /* Sequencing of unknown local commit */);
182
- this.inFlightQueue.shift();
183
- } else {
184
- // A peer commit has been sequenced
135
+ public onSequencedCommitApplied(revision: RevisionTag, isLocal: boolean): void {
136
+ // We no longer need to track enrichment for the commit with this revision.
137
+ // Note that we may have a commit for this revision even if this is not a local change,
138
+ // as this client and another peer may have merged the same commit from a shared branch.
139
+ this.pendingChanges.delete(revision);
140
+ if (!isLocal) {
141
+ // A peer commit has been sequenced, invalidating the enrichment of our in-flight commits.
185
142
  this.currentEnrichment++;
186
143
  }
187
144
  }