@fluidframework/tree 2.116.0 → 2.117.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 (362) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/api-report/tree.alpha.api.md +78 -30
  3. package/api-report/tree.beta.api.md +12 -9
  4. package/api-report/tree.legacy.beta.api.md +12 -9
  5. package/dist/codec/codec.d.ts +18 -0
  6. package/dist/codec/codec.d.ts.map +1 -1
  7. package/dist/codec/codec.js +18 -0
  8. package/dist/codec/codec.js.map +1 -1
  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 +3 -2
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/rebase/index.d.ts +1 -1
  14. package/dist/core/rebase/index.d.ts.map +1 -1
  15. package/dist/core/rebase/index.js +2 -1
  16. package/dist/core/rebase/index.js.map +1 -1
  17. package/dist/core/rebase/types.d.ts +39 -2
  18. package/dist/core/rebase/types.d.ts.map +1 -1
  19. package/dist/core/rebase/types.js +37 -2
  20. package/dist/core/rebase/types.js.map +1 -1
  21. package/dist/core/rebase/utils.d.ts.map +1 -1
  22. package/dist/core/rebase/utils.js +1 -0
  23. package/dist/core/rebase/utils.js.map +1 -1
  24. package/dist/core/revertible.d.ts +62 -6
  25. package/dist/core/revertible.d.ts.map +1 -1
  26. package/dist/core/revertible.js.map +1 -1
  27. package/dist/entrypoints/alpha.d.ts +1 -1
  28. package/dist/entrypoints/alpha.d.ts.map +1 -1
  29. package/dist/entrypoints/alpha.js.map +1 -1
  30. package/dist/entrypoints/beta.d.ts +1 -1
  31. package/dist/entrypoints/beta.d.ts.map +1 -1
  32. package/dist/entrypoints/beta.js.map +1 -1
  33. package/dist/entrypoints/legacy.d.ts +1 -1
  34. package/dist/entrypoints/legacy.d.ts.map +1 -1
  35. package/dist/entrypoints/legacy.js.map +1 -1
  36. package/dist/feature-libraries/indexing/types.d.ts +1 -1
  37. package/dist/feature-libraries/indexing/types.js.map +1 -1
  38. package/dist/index.d.ts +2 -2
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/packageVersion.d.ts +1 -1
  42. package/dist/packageVersion.js +1 -1
  43. package/dist/packageVersion.js.map +1 -1
  44. package/dist/shared-tree/history.d.ts +22 -0
  45. package/dist/shared-tree/history.d.ts.map +1 -0
  46. package/dist/shared-tree/history.js +66 -0
  47. package/dist/shared-tree/history.js.map +1 -0
  48. package/dist/shared-tree/schematizingTreeView.d.ts +12 -7
  49. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  50. package/dist/shared-tree/schematizingTreeView.js +13 -0
  51. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  52. package/dist/shared-tree/sharedTree.d.ts +3 -2
  53. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  54. package/dist/shared-tree/sharedTree.js +2 -0
  55. package/dist/shared-tree/sharedTree.js.map +1 -1
  56. package/dist/shared-tree/tree.js +1 -1
  57. package/dist/shared-tree/tree.js.map +1 -1
  58. package/dist/shared-tree/treeAlpha.d.ts +8 -20
  59. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  60. package/dist/shared-tree/treeAlpha.js +9 -12
  61. package/dist/shared-tree/treeAlpha.js.map +1 -1
  62. package/dist/shared-tree/treeCheckout.d.ts +16 -9
  63. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  64. package/dist/shared-tree/treeCheckout.js +130 -33
  65. package/dist/shared-tree/treeCheckout.js.map +1 -1
  66. package/dist/shared-tree/unhydratedTreeContext.d.ts +3 -2
  67. package/dist/shared-tree/unhydratedTreeContext.d.ts.map +1 -1
  68. package/dist/shared-tree/unhydratedTreeContext.js +3 -0
  69. package/dist/shared-tree/unhydratedTreeContext.js.map +1 -1
  70. package/dist/shared-tree-core/branch.d.ts +16 -2
  71. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  72. package/dist/shared-tree-core/branch.js +20 -2
  73. package/dist/shared-tree-core/branch.js.map +1 -1
  74. package/dist/shared-tree-core/branchCommitCounter.d.ts +31 -0
  75. package/dist/shared-tree-core/branchCommitCounter.d.ts.map +1 -0
  76. package/dist/shared-tree-core/branchCommitCounter.js +79 -0
  77. package/dist/shared-tree-core/branchCommitCounter.js.map +1 -0
  78. package/dist/shared-tree-core/customMetadataCodec.d.ts +9 -0
  79. package/dist/shared-tree-core/customMetadataCodec.d.ts.map +1 -0
  80. package/dist/shared-tree-core/customMetadataCodec.js +37 -0
  81. package/dist/shared-tree-core/customMetadataCodec.js.map +1 -0
  82. package/dist/shared-tree-core/customMetadataFormat.d.ts +18 -0
  83. package/dist/shared-tree-core/customMetadataFormat.d.ts.map +1 -0
  84. package/dist/shared-tree-core/customMetadataFormat.js +15 -0
  85. package/dist/shared-tree-core/customMetadataFormat.js.map +1 -0
  86. package/dist/shared-tree-core/editManager.d.ts.map +1 -1
  87. package/dist/shared-tree-core/editManager.js +15 -3
  88. package/dist/shared-tree-core/editManager.js.map +1 -1
  89. package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  90. package/dist/shared-tree-core/editManagerCodecs.js +5 -0
  91. package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
  92. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +1 -1
  93. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  94. package/dist/shared-tree-core/editManagerCodecsCommons.js +17 -5
  95. package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  96. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  97. package/dist/shared-tree-core/editManagerCodecsV1toV4.js +4 -2
  98. package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  99. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  100. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js +2 -2
  101. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  102. package/dist/shared-tree-core/editManagerFormatCommons.d.ts +17 -6
  103. package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
  104. package/dist/shared-tree-core/editManagerFormatCommons.js +18 -8
  105. package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  106. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +7 -5
  107. package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
  108. package/dist/shared-tree-core/editManagerFormatV1toV4.js +4 -3
  109. package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  110. package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts +4 -0
  111. package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -1
  112. package/dist/shared-tree-core/editManagerFormatVSharedBranches.js +2 -2
  113. package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
  114. package/dist/shared-tree-core/index.d.ts +2 -1
  115. package/dist/shared-tree-core/index.d.ts.map +1 -1
  116. package/dist/shared-tree-core/index.js +3 -1
  117. package/dist/shared-tree-core/index.js.map +1 -1
  118. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts +2 -2
  119. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  120. package/dist/shared-tree-core/messageCodecV1ToV4.js +12 -3
  121. package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  122. package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  123. package/dist/shared-tree-core/messageCodecVSharedBranches.js +8 -2
  124. package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  125. package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
  126. package/dist/shared-tree-core/messageCodecs.js +5 -0
  127. package/dist/shared-tree-core/messageCodecs.js.map +1 -1
  128. package/dist/shared-tree-core/messageFormat.d.ts +1 -0
  129. package/dist/shared-tree-core/messageFormat.d.ts.map +1 -1
  130. package/dist/shared-tree-core/messageFormat.js +6 -0
  131. package/dist/shared-tree-core/messageFormat.js.map +1 -1
  132. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +10 -3
  133. package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
  134. package/dist/shared-tree-core/messageFormatV1ToV4.js +10 -2
  135. package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  136. package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts +7 -0
  137. package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -1
  138. package/dist/shared-tree-core/messageFormatVSharedBranches.js +2 -0
  139. package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
  140. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  141. package/dist/shared-tree-core/sharedTreeCore.js +4 -2
  142. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  143. package/dist/shared-tree-core/transaction.d.ts +9 -0
  144. package/dist/shared-tree-core/transaction.d.ts.map +1 -1
  145. package/dist/shared-tree-core/transaction.js +26 -4
  146. package/dist/shared-tree-core/transaction.js.map +1 -1
  147. package/dist/simple-tree/api/index.d.ts +1 -1
  148. package/dist/simple-tree/api/index.d.ts.map +1 -1
  149. package/dist/simple-tree/api/index.js.map +1 -1
  150. package/dist/simple-tree/api/transactionTypes.d.ts +28 -2
  151. package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
  152. package/dist/simple-tree/api/transactionTypes.js.map +1 -1
  153. package/dist/simple-tree/api/tree.d.ts +180 -61
  154. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  155. package/dist/simple-tree/api/tree.js.map +1 -1
  156. package/dist/simple-tree/index.d.ts +1 -1
  157. package/dist/simple-tree/index.d.ts.map +1 -1
  158. package/dist/simple-tree/index.js.map +1 -1
  159. package/dist/tableSchema.js +10 -10
  160. package/dist/tableSchema.js.map +1 -1
  161. package/lib/codec/codec.d.ts +18 -0
  162. package/lib/codec/codec.d.ts.map +1 -1
  163. package/lib/codec/codec.js +18 -0
  164. package/lib/codec/codec.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/rebase/index.d.ts +1 -1
  170. package/lib/core/rebase/index.d.ts.map +1 -1
  171. package/lib/core/rebase/index.js +1 -1
  172. package/lib/core/rebase/index.js.map +1 -1
  173. package/lib/core/rebase/types.d.ts +39 -2
  174. package/lib/core/rebase/types.d.ts.map +1 -1
  175. package/lib/core/rebase/types.js +35 -1
  176. package/lib/core/rebase/types.js.map +1 -1
  177. package/lib/core/rebase/utils.d.ts.map +1 -1
  178. package/lib/core/rebase/utils.js +1 -0
  179. package/lib/core/rebase/utils.js.map +1 -1
  180. package/lib/core/revertible.d.ts +62 -6
  181. package/lib/core/revertible.d.ts.map +1 -1
  182. package/lib/core/revertible.js.map +1 -1
  183. package/lib/entrypoints/alpha.d.ts +1 -1
  184. package/lib/entrypoints/alpha.d.ts.map +1 -1
  185. package/lib/entrypoints/alpha.js.map +1 -1
  186. package/lib/entrypoints/beta.d.ts +1 -1
  187. package/lib/entrypoints/beta.d.ts.map +1 -1
  188. package/lib/entrypoints/beta.js.map +1 -1
  189. package/lib/entrypoints/legacy.d.ts +1 -1
  190. package/lib/entrypoints/legacy.d.ts.map +1 -1
  191. package/lib/entrypoints/legacy.js.map +1 -1
  192. package/lib/feature-libraries/indexing/types.d.ts +1 -1
  193. package/lib/feature-libraries/indexing/types.js.map +1 -1
  194. package/lib/index.d.ts +2 -2
  195. package/lib/index.d.ts.map +1 -1
  196. package/lib/index.js.map +1 -1
  197. package/lib/packageVersion.d.ts +1 -1
  198. package/lib/packageVersion.js +1 -1
  199. package/lib/packageVersion.js.map +1 -1
  200. package/lib/shared-tree/history.d.ts +22 -0
  201. package/lib/shared-tree/history.d.ts.map +1 -0
  202. package/lib/shared-tree/history.js +62 -0
  203. package/lib/shared-tree/history.js.map +1 -0
  204. package/lib/shared-tree/schematizingTreeView.d.ts +12 -7
  205. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  206. package/lib/shared-tree/schematizingTreeView.js +13 -0
  207. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  208. package/lib/shared-tree/sharedTree.d.ts +3 -2
  209. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  210. package/lib/shared-tree/sharedTree.js +2 -0
  211. package/lib/shared-tree/sharedTree.js.map +1 -1
  212. package/lib/shared-tree/tree.js +1 -1
  213. package/lib/shared-tree/tree.js.map +1 -1
  214. package/lib/shared-tree/treeAlpha.d.ts +8 -20
  215. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  216. package/lib/shared-tree/treeAlpha.js +9 -12
  217. package/lib/shared-tree/treeAlpha.js.map +1 -1
  218. package/lib/shared-tree/treeCheckout.d.ts +16 -9
  219. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  220. package/lib/shared-tree/treeCheckout.js +131 -34
  221. package/lib/shared-tree/treeCheckout.js.map +1 -1
  222. package/lib/shared-tree/unhydratedTreeContext.d.ts +3 -2
  223. package/lib/shared-tree/unhydratedTreeContext.d.ts.map +1 -1
  224. package/lib/shared-tree/unhydratedTreeContext.js +3 -0
  225. package/lib/shared-tree/unhydratedTreeContext.js.map +1 -1
  226. package/lib/shared-tree-core/branch.d.ts +16 -2
  227. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  228. package/lib/shared-tree-core/branch.js +20 -2
  229. package/lib/shared-tree-core/branch.js.map +1 -1
  230. package/lib/shared-tree-core/branchCommitCounter.d.ts +31 -0
  231. package/lib/shared-tree-core/branchCommitCounter.d.ts.map +1 -0
  232. package/lib/shared-tree-core/branchCommitCounter.js +75 -0
  233. package/lib/shared-tree-core/branchCommitCounter.js.map +1 -0
  234. package/lib/shared-tree-core/customMetadataCodec.d.ts +9 -0
  235. package/lib/shared-tree-core/customMetadataCodec.d.ts.map +1 -0
  236. package/lib/shared-tree-core/customMetadataCodec.js +32 -0
  237. package/lib/shared-tree-core/customMetadataCodec.js.map +1 -0
  238. package/lib/shared-tree-core/customMetadataFormat.d.ts +18 -0
  239. package/lib/shared-tree-core/customMetadataFormat.d.ts.map +1 -0
  240. package/lib/shared-tree-core/customMetadataFormat.js +11 -0
  241. package/lib/shared-tree-core/customMetadataFormat.js.map +1 -0
  242. package/lib/shared-tree-core/editManager.d.ts.map +1 -1
  243. package/lib/shared-tree-core/editManager.js +16 -4
  244. package/lib/shared-tree-core/editManager.js.map +1 -1
  245. package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
  246. package/lib/shared-tree-core/editManagerCodecs.js +5 -0
  247. package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
  248. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +1 -1
  249. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  250. package/lib/shared-tree-core/editManagerCodecsCommons.js +17 -5
  251. package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  252. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  253. package/lib/shared-tree-core/editManagerCodecsV1toV4.js +4 -2
  254. package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  255. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  256. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js +2 -2
  257. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  258. package/lib/shared-tree-core/editManagerFormatCommons.d.ts +17 -6
  259. package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
  260. package/lib/shared-tree-core/editManagerFormatCommons.js +18 -8
  261. package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  262. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +7 -5
  263. package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
  264. package/lib/shared-tree-core/editManagerFormatV1toV4.js +4 -3
  265. package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  266. package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts +4 -0
  267. package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -1
  268. package/lib/shared-tree-core/editManagerFormatVSharedBranches.js +2 -2
  269. package/lib/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
  270. package/lib/shared-tree-core/index.d.ts +2 -1
  271. package/lib/shared-tree-core/index.d.ts.map +1 -1
  272. package/lib/shared-tree-core/index.js +1 -0
  273. package/lib/shared-tree-core/index.js.map +1 -1
  274. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts +2 -2
  275. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  276. package/lib/shared-tree-core/messageCodecV1ToV4.js +12 -3
  277. package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  278. package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
  279. package/lib/shared-tree-core/messageCodecVSharedBranches.js +8 -2
  280. package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  281. package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
  282. package/lib/shared-tree-core/messageCodecs.js +5 -0
  283. package/lib/shared-tree-core/messageCodecs.js.map +1 -1
  284. package/lib/shared-tree-core/messageFormat.d.ts +1 -0
  285. package/lib/shared-tree-core/messageFormat.d.ts.map +1 -1
  286. package/lib/shared-tree-core/messageFormat.js +6 -0
  287. package/lib/shared-tree-core/messageFormat.js.map +1 -1
  288. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +10 -3
  289. package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
  290. package/lib/shared-tree-core/messageFormatV1ToV4.js +10 -2
  291. package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  292. package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts +7 -0
  293. package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -1
  294. package/lib/shared-tree-core/messageFormatVSharedBranches.js +2 -0
  295. package/lib/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
  296. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  297. package/lib/shared-tree-core/sharedTreeCore.js +5 -3
  298. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  299. package/lib/shared-tree-core/transaction.d.ts +9 -0
  300. package/lib/shared-tree-core/transaction.d.ts.map +1 -1
  301. package/lib/shared-tree-core/transaction.js +27 -5
  302. package/lib/shared-tree-core/transaction.js.map +1 -1
  303. package/lib/simple-tree/api/index.d.ts +1 -1
  304. package/lib/simple-tree/api/index.d.ts.map +1 -1
  305. package/lib/simple-tree/api/index.js.map +1 -1
  306. package/lib/simple-tree/api/transactionTypes.d.ts +28 -2
  307. package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
  308. package/lib/simple-tree/api/transactionTypes.js.map +1 -1
  309. package/lib/simple-tree/api/tree.d.ts +180 -61
  310. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  311. package/lib/simple-tree/api/tree.js.map +1 -1
  312. package/lib/simple-tree/index.d.ts +1 -1
  313. package/lib/simple-tree/index.d.ts.map +1 -1
  314. package/lib/simple-tree/index.js.map +1 -1
  315. package/lib/tableSchema.js +10 -10
  316. package/lib/tableSchema.js.map +1 -1
  317. package/package.json +23 -23
  318. package/src/codec/codec.ts +19 -0
  319. package/src/core/index.ts +4 -0
  320. package/src/core/rebase/index.ts +2 -0
  321. package/src/core/rebase/types.ts +72 -2
  322. package/src/core/rebase/utils.ts +1 -0
  323. package/src/core/revertible.ts +67 -6
  324. package/src/entrypoints/alpha.ts +8 -0
  325. package/src/entrypoints/beta.ts +1 -0
  326. package/src/entrypoints/legacy.ts +1 -0
  327. package/src/feature-libraries/indexing/types.ts +1 -1
  328. package/src/index.ts +8 -0
  329. package/src/packageVersion.ts +1 -1
  330. package/src/shared-tree/history.ts +99 -0
  331. package/src/shared-tree/schematizingTreeView.ts +25 -8
  332. package/src/shared-tree/sharedTree.ts +5 -2
  333. package/src/shared-tree/tree.ts +1 -1
  334. package/src/shared-tree/treeAlpha.ts +17 -35
  335. package/src/shared-tree/treeCheckout.ts +178 -39
  336. package/src/shared-tree/unhydratedTreeContext.ts +6 -2
  337. package/src/shared-tree-core/branch.ts +34 -2
  338. package/src/shared-tree-core/branchCommitCounter.ts +103 -0
  339. package/src/shared-tree-core/customMetadataCodec.ts +42 -0
  340. package/src/shared-tree-core/customMetadataFormat.ts +39 -0
  341. package/src/shared-tree-core/editManager.ts +22 -3
  342. package/src/shared-tree-core/editManagerCodecs.ts +12 -0
  343. package/src/shared-tree-core/editManagerCodecsCommons.ts +41 -15
  344. package/src/shared-tree-core/editManagerCodecsV1toV4.ts +7 -1
  345. package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +2 -0
  346. package/src/shared-tree-core/editManagerFormatCommons.ts +46 -12
  347. package/src/shared-tree-core/editManagerFormatV1toV4.ts +13 -5
  348. package/src/shared-tree-core/editManagerFormatVSharedBranches.ts +2 -2
  349. package/src/shared-tree-core/index.ts +3 -0
  350. package/src/shared-tree-core/messageCodecV1ToV4.ts +18 -5
  351. package/src/shared-tree-core/messageCodecVSharedBranches.ts +9 -2
  352. package/src/shared-tree-core/messageCodecs.ts +12 -0
  353. package/src/shared-tree-core/messageFormat.ts +6 -0
  354. package/src/shared-tree-core/messageFormatV1ToV4.ts +21 -3
  355. package/src/shared-tree-core/messageFormatVSharedBranches.ts +8 -0
  356. package/src/shared-tree-core/sharedTreeCore.ts +5 -2
  357. package/src/shared-tree-core/transaction.ts +56 -4
  358. package/src/simple-tree/api/index.ts +5 -0
  359. package/src/simple-tree/api/transactionTypes.ts +29 -2
  360. package/src/simple-tree/api/tree.ts +199 -60
  361. package/src/simple-tree/index.ts +5 -0
  362. package/src/tableSchema.ts +9 -9
@@ -17,6 +17,7 @@ import {
17
17
  type ChangeFamily,
18
18
  type ChangeFamilyEditor,
19
19
  CommitKind,
20
+ type CustomMetadataTree,
20
21
  type GraphCommit,
21
22
  type RevisionTag,
22
23
  type TaggedChange,
@@ -56,6 +57,10 @@ export type SharedTreeBranchChange<TChange> =
56
57
  | {
57
58
  type: "rebase";
58
59
  change: TaggedChange<TChange> | undefined;
60
+ /** The commits removed from the head of the branch by this operation */
61
+ removedCommits: readonly GraphCommit<TChange>[];
62
+ /** The commits appended to the head of the branch by this operation */
63
+ newCommits: readonly GraphCommit<TChange>[];
59
64
  };
60
65
 
61
66
  /**
@@ -152,7 +157,7 @@ export class SharedTreeBranch<
152
157
  >,
153
158
  ) {
154
159
  this.editor = this.changeFamily.buildEditor(mintRevisionTag, (change) =>
155
- this.apply(change),
160
+ this.apply(change, CommitKind.Default, undefined),
156
161
  );
157
162
  this.unsubscribeBranchTrimmer = branchTrimmer?.on("ancestryTrimmed", (commit) => {
158
163
  this.#events.emit("ancestryTrimmed", commit);
@@ -173,9 +178,15 @@ export class SharedTreeBranch<
173
178
  * Apply a change to this branch.
174
179
  * @param change - the change to apply
175
180
  * @param kind - the kind of change to apply
181
+ * @param customMetadata - {@link GraphCommit.customMetadata | metadata} to attach to the new commit.
182
+ * Callers reconstructing an existing commit, rather than minting one, must pass that commit's metadata.
176
183
  * @returns the change that was applied and the new head commit of the branch
177
184
  */
178
- public apply(change: TaggedChange<TChange>, kind: CommitKind = CommitKind.Default): void {
185
+ public apply(
186
+ change: TaggedChange<TChange>,
187
+ kind: CommitKind,
188
+ customMetadata: CustomMetadataTree | undefined,
189
+ ): void {
179
190
  this.assertNotDisposed();
180
191
 
181
192
  const revisionTag = change.revision;
@@ -184,6 +195,7 @@ export class SharedTreeBranch<
184
195
  const newHead = mintCommit(this.head, {
185
196
  revision: revisionTag,
186
197
  change: change.change,
198
+ customMetadata,
187
199
  });
188
200
 
189
201
  const changeEvent = {
@@ -213,6 +225,26 @@ export class SharedTreeBranch<
213
225
  return this.head;
214
226
  }
215
227
 
228
+ /**
229
+ * Gets the number of commits in this branch.
230
+ * This includes commits on ancestor branches but excludes the sentinel commit at the root of all branches.
231
+ * @remarks
232
+ * This method has linear complexity in the number of commits in the branch.
233
+ * See {@link BranchCommitCounter} for a cached version.
234
+ */
235
+ public getCommitCount(): number {
236
+ let count = 0;
237
+ for (
238
+ let commit: GraphCommit<TChange> | undefined = this.head;
239
+ commit !== undefined;
240
+ commit = commit.parent
241
+ ) {
242
+ count++;
243
+ }
244
+ // Exclude the sentinel commit that serves as the base to all branches.
245
+ return count - 1;
246
+ }
247
+
216
248
  /**
217
249
  * Spawn a new branch that is based off of the current state of this branch.
218
250
  * @param commit - The commit to base the new branch off of. Defaults to the head of this branch.
@@ -0,0 +1,103 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
7
+
8
+ import type { ChangeFamilyEditor, RevisionTag } from "../core/index.js";
9
+ import type { SharedTreeBranch, SharedTreeBranchChange } from "./branch.js";
10
+
11
+ /**
12
+ * A utility class that counts the number of commits in a branch and keeps the count updated as the branch changes.
13
+ *
14
+ * @remarks
15
+ * This class has no inside knowledge of what the commits represent.
16
+ * It is therefore oblivious to any scheme where some root commit is considered "special" and should not be counted.
17
+ */
18
+ export class BranchCommitCounter<
19
+ TEditor extends ChangeFamilyEditor,
20
+ TChange,
21
+ TChangeProcessingContext,
22
+ > {
23
+ private unsubscribeAfterChange?: () => void;
24
+ private unsubscribeAncestryTrimmed?: () => void;
25
+ private commitCountInitialized: boolean = false;
26
+ private cachedCommitCount: number = 0;
27
+
28
+ public constructor(
29
+ private readonly branch: SharedTreeBranch<TEditor, TChange, TChangeProcessingContext>,
30
+ ) {}
31
+
32
+ public dispose(): void {
33
+ this.unsubscribeFromBranch();
34
+ }
35
+
36
+ /**
37
+ * Gets the number of commits in the branch.
38
+ */
39
+ public get count(): number {
40
+ if (!this.commitCountInitialized) {
41
+ this.cachedCommitCount = this.branch.getCommitCount();
42
+ this.subscribeToBranch();
43
+ this.commitCountInitialized = true;
44
+ }
45
+ return this.cachedCommitCount;
46
+ }
47
+
48
+ private subscribeToBranch(): void {
49
+ this.unsubscribeFromBranch();
50
+ this.unsubscribeAfterChange = this.branch.events.on(
51
+ "afterChange",
52
+ this.onAfterBranchChange,
53
+ );
54
+ this.unsubscribeAncestryTrimmed = this.branch.events.on(
55
+ "ancestryTrimmed",
56
+ this.onAncestryTrimmed,
57
+ );
58
+ }
59
+
60
+ private unsubscribeFromBranch(): void {
61
+ this.unsubscribeAfterChange?.();
62
+ this.unsubscribeAfterChange = undefined;
63
+ this.unsubscribeAncestryTrimmed?.();
64
+ this.unsubscribeAncestryTrimmed = undefined;
65
+ }
66
+
67
+ private readonly onAfterBranchChange = (event: SharedTreeBranchChange<TChange>): void => {
68
+ if (!this.commitCountInitialized) {
69
+ return;
70
+ }
71
+
72
+ switch (event.type) {
73
+ case "append": {
74
+ this.cachedCommitCount += event.newCommits.length;
75
+ return;
76
+ }
77
+ case "remove": {
78
+ this.cachedCommitCount -= event.removedCommits.length;
79
+ return;
80
+ }
81
+ case "rebase": {
82
+ this.cachedCommitCount += event.newCommits.length;
83
+ this.cachedCommitCount -= event.removedCommits.length;
84
+ return;
85
+ }
86
+ default: {
87
+ unreachableCase(event);
88
+ }
89
+ }
90
+ };
91
+
92
+ private readonly onAncestryTrimmed = (trimmedRevisions: RevisionTag[]): void => {
93
+ if (!this.commitCountInitialized) {
94
+ return;
95
+ }
96
+
97
+ assert(
98
+ this.cachedCommitCount >= trimmedRevisions.length,
99
+ 0xd35 /* Trimmed more commits than exist in the branch */,
100
+ );
101
+ this.cachedCommitCount = this.cachedCommitCount - trimmedRevisions.length;
102
+ };
103
+ }
@@ -0,0 +1,42 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type { CustomMetadataTree } from "../core/index.js";
7
+ import type { Mutable } from "../util/index.js";
8
+
9
+ import type { EncodedCustomMetadataTree } from "./customMetadataFormat.js";
10
+
11
+ export function encodeCustomMetadataTree(tree: CustomMetadataTree): EncodedCustomMetadataTree {
12
+ const encoded: Mutable<EncodedCustomMetadataTree> = {};
13
+ if (tree.metadata !== undefined) {
14
+ encoded.m = tree.metadata;
15
+ }
16
+ if (tree.children.length > 0) {
17
+ encoded.c = tree.children.map(encodeCustomMetadataTree);
18
+ }
19
+ return encoded;
20
+ }
21
+
22
+ export function decodeCustomMetadataTree(
23
+ encoded: EncodedCustomMetadataTree | undefined,
24
+ ): CustomMetadataTree | undefined {
25
+ if (encoded === undefined) {
26
+ return undefined;
27
+ }
28
+ const decoded = decodeNode(encoded);
29
+ // A tree in which no node supplied metadata carries no information.
30
+ return hasMetadata(decoded) ? decoded : undefined;
31
+ }
32
+
33
+ function decodeNode(encoded: EncodedCustomMetadataTree): CustomMetadataTree {
34
+ return {
35
+ metadata: encoded.m,
36
+ children: encoded.c?.map(decodeNode) ?? [],
37
+ };
38
+ }
39
+
40
+ function hasMetadata(node: CustomMetadataTree): boolean {
41
+ return node.metadata !== undefined || node.children.some(hasMetadata);
42
+ }
@@ -0,0 +1,39 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import * as Type from "@sinclair/typebox";
7
+
8
+ import {
9
+ type JsonCompatibleReadOnlyObject,
10
+ JsonCompatibleReadOnlySchema,
11
+ } from "../util/index.js";
12
+
13
+ /**
14
+ * The persisted form of a {@link CustomMetadataTree}.
15
+ * @remarks
16
+ * The property names (`m` for metadata, `c` for children) are abbreviated and both are optional because
17
+ * this rides on every annotated op and occupies summary space for as long as its commit survives.
18
+ */
19
+ // Declared as a type alias rather than an interface so that it satisfies the index signature of
20
+ // `JsonCompatibleReadOnlyObject`, which the encoded message and summary types are constrained to.
21
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
22
+ export type EncodedCustomMetadataTree = {
23
+ readonly m?: JsonCompatibleReadOnlyObject;
24
+ readonly c?: readonly EncodedCustomMetadataTree[];
25
+ };
26
+
27
+ export const EncodedCustomMetadataTree = Type.Recursive((Self) =>
28
+ Type.Object(
29
+ {
30
+ m: Type.Optional(
31
+ Type.Unsafe<JsonCompatibleReadOnlyObject>(
32
+ Type.Record(Type.String(), JsonCompatibleReadOnlySchema),
33
+ ),
34
+ ),
35
+ c: Type.Optional(Type.Array(Self)),
36
+ },
37
+ { additionalProperties: false },
38
+ ),
39
+ ) as unknown as Type.TSchema;
@@ -17,6 +17,7 @@ import { BTree } from "@tylerbu/sorted-btree-es6";
17
17
  import {
18
18
  type ChangeFamily,
19
19
  type ChangeFamilyEditor,
20
+ CommitKind,
20
21
  type GraphCommit,
21
22
  type RevisionTag,
22
23
  findAncestor,
@@ -134,6 +135,7 @@ export class EditManager<
134
135
  this.trunkBase = {
135
136
  revision: rootRevision,
136
137
  change: changeFamily.rebaser.compose([]),
138
+ customMetadata: undefined,
137
139
  };
138
140
 
139
141
  if (logger !== undefined) {
@@ -348,6 +350,11 @@ export class EditManager<
348
350
  // so rebase them accordingly. This is necessary to prevent peer branches from referencing any evicted commits.
349
351
  mainBranch.trimHistory(latestEvicted, sequenceId);
350
352
 
353
+ // Custom metadata shares the lifetime of its commit, so it must be dropped when the commit is
354
+ // trimmed. The new trunk base stays reachable as the sentinel for the remaining history, so its
355
+ // metadata is cleared rather than trapped; fully evicted commits get the throwing trap below.
356
+ (newTrunkBase as Mutable<typeof newTrunkBase>).customMetadata = undefined;
357
+
351
358
  // Only the last trimmed commit, which is the new trunk base, should remain accessible.
352
359
  for (const commit of trimmedCommits.slice(0, -1)) {
353
360
  Reflect.defineProperty(commit, "change", {
@@ -363,6 +370,10 @@ export class EditManager<
363
370
  Reflect.defineProperty(commit, "parent", {
364
371
  get: () => fail(0xa60 /* Should not access 'parent' property of an evicted commit */),
365
372
  });
373
+ Reflect.defineProperty(commit, "customMetadata", {
374
+ get: () =>
375
+ fail(0xd36 /* Should not access 'customMetadata' property of an evicted commit */),
376
+ });
366
377
  }
367
378
 
368
379
  // Dropping the parent field removes (transitively) all references to the evicted commits so they can be garbage collected.
@@ -386,11 +397,13 @@ export class EditManager<
386
397
  // Trimming the trunk before serializing ensures that the trunk data in the summary is as minimal as possible.
387
398
  this.trimHistory();
388
399
 
400
+ const mainBranch = this.getSharedBranch("main");
389
401
  const minSeqNumberToSummarize: SequenceId = {
390
402
  sequenceNumber: brand(this.minimumSequenceNumber + 1),
391
403
  };
392
- let minBaseSeqId: SequenceId = minSeqNumberToSummarize;
393
- const mainBranch = this.getSharedBranch("main");
404
+ let minBaseSeqId: SequenceId = this.retainHistory
405
+ ? (mainBranch.sequenceIdToCommit.minKey() ?? minimumPossibleSequenceId)
406
+ : minSeqNumberToSummarize;
394
407
  const branches = new Map<BranchId, SharedBranchSummaryData<TChangeset>>();
395
408
  for (const [branchId, branch] of this.sharedBranches) {
396
409
  if (branchId !== "main") {
@@ -822,7 +835,11 @@ class SharedBranch<TEditor extends ChangeFamilyEditor, TChangeset, TChangeProces
822
835
  } else {
823
836
  // Otherwise, push the changes to the peer local branch and merge the branch into the trunk.
824
837
  for (const newCommit of newCommits) {
825
- peerLocalBranch.apply(tagChange(newCommit.change, newCommit.revision));
838
+ peerLocalBranch.apply(
839
+ tagChange(newCommit.change, newCommit.revision),
840
+ CommitKind.Default,
841
+ newCommit.customMetadata,
842
+ );
826
843
  }
827
844
  const result = this.trunk.merge(peerLocalBranch);
828
845
  if (result !== undefined) {
@@ -1089,6 +1106,7 @@ class SharedBranch<TEditor extends ChangeFamilyEditor, TChangeset, TChangeProces
1089
1106
  revision: c.revision,
1090
1107
  sequenceNumber: metadata.sequenceId.sequenceNumber,
1091
1108
  sessionId: metadata.sessionId,
1109
+ customMetadata: c.customMetadata,
1092
1110
  };
1093
1111
  if (metadata.sequenceId.indexInBatch !== undefined) {
1094
1112
  commit.indexInBatch = metadata.sequenceId.indexInBatch;
@@ -1114,6 +1132,7 @@ class SharedBranch<TEditor extends ChangeFamilyEditor, TChangeset, TChangeProces
1114
1132
  change: c.change,
1115
1133
  revision: c.revision,
1116
1134
  sessionId,
1135
+ customMetadata: c.customMetadata,
1117
1136
  };
1118
1137
  return commit;
1119
1138
  }),
@@ -108,6 +108,18 @@ export function makeEditManagerCodecBuilder<TChangeset>(): VersionDispatchingCod
108
108
  EditManagerFormatVersion.v6,
109
109
  ),
110
110
  },
111
+ {
112
+ minVersionForCollab: FluidClientVersion.v2_117,
113
+ formatVersion: EditManagerFormatVersion.v7,
114
+ codec: (options: EditManagerCodecOptions<TChangeset>) =>
115
+ makeV1toV4andV6CodecWithVersion(
116
+ options.changeCodecs.resolve(
117
+ options.dependentChangeFormatVersion.lookup(EditManagerFormatVersion.v7),
118
+ ),
119
+ options.revisionTagCodec,
120
+ EditManagerFormatVersion.v7,
121
+ ),
122
+ },
111
123
  {
112
124
  minVersionForCollab: undefined,
113
125
  formatVersion: EditManagerFormatVersion.vSharedBranches,
@@ -22,6 +22,7 @@ import {
22
22
  } from "../util/index.js";
23
23
 
24
24
  import { decodeBranchId, encodeBranchId } from "./branchIdCodec.js";
25
+ import { decodeCustomMetadataTree, encodeCustomMetadataTree } from "./customMetadataCodec.js";
25
26
  import type { SharedBranchSummaryData } from "./editManager.js";
26
27
  import type {
27
28
  Commit,
@@ -71,8 +72,9 @@ function encodeCommit<TChangeset, T extends Commit<TChangeset>>(
71
72
  >,
72
73
  commit: T,
73
74
  context: ChangeEncodingContext,
75
+ includeCustomMetadata: boolean,
74
76
  ) {
75
- return {
77
+ const encoded = {
76
78
  ...commit,
77
79
  revision: revisionTagCodec.encode(commit.revision, {
78
80
  originatorId: commit.sessionId,
@@ -82,6 +84,16 @@ function encodeCommit<TChangeset, T extends Commit<TChangeset>>(
82
84
  }),
83
85
  change: changeCodec.encode(commit.change, { ...context, revision: commit.revision }),
84
86
  };
87
+ // Rebuilt rather than spread through, both to convert it to the persisted form and so that a client
88
+ // writing an older format never emits a field that format does not define.
89
+ if (encoded.customMetadata === undefined) {
90
+ const { customMetadata: _, ...withoutMetadata } = encoded;
91
+ return withoutMetadata;
92
+ }
93
+ const { customMetadata, ...rest } = encoded;
94
+ return includeCustomMetadata
95
+ ? { ...rest, customMetadata: encodeCustomMetadataTree(customMetadata) }
96
+ : rest;
85
97
  }
86
98
 
87
99
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -112,6 +124,7 @@ function decodeCommit<TChangeset, T extends EncodedCommit<JsonCompatibleReadOnly
112
124
  ...commit,
113
125
  revision,
114
126
  change: changeCodec.decode(commit.change, { ...context, revision }),
127
+ customMetadata: decodeCustomMetadataTree(commit.customMetadata),
115
128
  };
116
129
  }
117
130
 
@@ -131,16 +144,23 @@ export function encodeSharedBranch<TChangeset>(
131
144
  data: SharedBranchSummaryData<TChangeset>,
132
145
  context: EditManagerEncodingContext,
133
146
  originatorId: SessionId | undefined,
147
+ includeCustomMetadata: boolean,
134
148
  ): EncodedSharedBranch<TChangeset> {
135
149
  const json: Mutable<EncodedSharedBranch<TChangeset>> = {
136
150
  trunk: data.trunk.map((commit) =>
137
- encodeCommit(changeCodec, revisionTagCodec, commit, {
138
- originatorId: commit.sessionId,
139
- idCompressor: context.idCompressor,
140
- schema: context.schema,
141
- revision: undefined,
142
- isSummary: context.isSummary,
143
- }),
151
+ encodeCommit(
152
+ changeCodec,
153
+ revisionTagCodec,
154
+ commit,
155
+ {
156
+ originatorId: commit.sessionId,
157
+ idCompressor: context.idCompressor,
158
+ schema: context.schema,
159
+ revision: undefined,
160
+ isSummary: context.isSummary,
161
+ },
162
+ includeCustomMetadata,
163
+ ),
144
164
  ),
145
165
  peers: Array.from(data.peerLocalBranches.entries(), ([sessionId, branch]) => [
146
166
  sessionId,
@@ -152,13 +172,19 @@ export function encodeSharedBranch<TChangeset>(
152
172
  isSummary: context.isSummary,
153
173
  }),
154
174
  commits: branch.commits.map((commit) =>
155
- encodeCommit(changeCodec, revisionTagCodec, commit, {
156
- originatorId: commit.sessionId,
157
- idCompressor: context.idCompressor,
158
- schema: context.schema,
159
- revision: undefined,
160
- isSummary: context.isSummary,
161
- }),
175
+ encodeCommit(
176
+ changeCodec,
177
+ revisionTagCodec,
178
+ commit,
179
+ {
180
+ originatorId: commit.sessionId,
181
+ idCompressor: context.idCompressor,
182
+ schema: context.schema,
183
+ revision: undefined,
184
+ isSummary: context.isSummary,
185
+ },
186
+ includeCustomMetadata,
187
+ ),
162
188
  ),
163
189
  },
164
190
  ]),
@@ -19,6 +19,7 @@ import {
19
19
  type EditManagerEncodingContext,
20
20
  } from "./editManagerCodecsCommons.js";
21
21
  import { EncodedEditManager } from "./editManagerFormatV1toV4.js";
22
+ import { EditManagerFormatVersion } from "./editManagerFormatCommons.js";
22
23
 
23
24
  /**
24
25
  * Create the provided version of the {@link EditManager} codec (which encodes it's {@link SummaryData}).
@@ -47,7 +48,11 @@ export function makeV1toV4andV6CodecWithVersion<TChangeset>(
47
48
  EditManagerEncodingContext,
48
49
  EditManagerDecodingContext
49
50
  > {
50
- const schema = EncodedEditManager(changeCodec.encodedSchema ?? JsonCompatibleReadOnlySchema);
51
+ const includeCustomMetadata = version >= EditManagerFormatVersion.v7;
52
+ const schema = EncodedEditManager(
53
+ changeCodec.encodedSchema ?? JsonCompatibleReadOnlySchema,
54
+ includeCustomMetadata,
55
+ );
51
56
 
52
57
  const codec: CodecAndSchema<
53
58
  SummaryData<TChangeset>,
@@ -65,6 +70,7 @@ export function makeV1toV4andV6CodecWithVersion<TChangeset>(
65
70
  data.main,
66
71
  context,
67
72
  data.originator,
73
+ includeCustomMetadata,
68
74
  );
69
75
  const encoded: EncodedEditManager<TChangeset> = {
70
76
  trunk: mainBranch.trunk,
@@ -59,6 +59,7 @@ export function makeSharedBranchesCodecWithVersion<TChangeset>(
59
59
  data.main,
60
60
  context,
61
61
  data.originator,
62
+ true,
62
63
  );
63
64
  assert(
64
65
  data.originator !== undefined,
@@ -79,6 +80,7 @@ export function makeSharedBranchesCodecWithVersion<TChangeset>(
79
80
  branch,
80
81
  context,
81
82
  data.originator,
83
+ true,
82
84
  ),
83
85
  );
84
86
  }
@@ -8,6 +8,7 @@ import * as Type from "@sinclair/typebox";
8
8
  import type { ObjectOptions, Static, TSchema } from "@sinclair/typebox";
9
9
 
10
10
  import {
11
+ type CustomMetadataTree,
11
12
  type EncodedRevisionTag,
12
13
  type RevisionTag,
13
14
  RevisionTagSchema,
@@ -16,6 +17,7 @@ import {
16
17
  import { type Brand, brandedNumberType, strictEnum, type Values } from "../util/index.js";
17
18
 
18
19
  import type { EncodedBranchId } from "./branch.js";
20
+ import { EncodedCustomMetadataTree } from "./customMetadataFormat.js";
19
21
 
20
22
  /**
21
23
  * Contains a single change to the `SharedTree` and associated metadata.
@@ -28,6 +30,8 @@ export interface Commit<TChangeset> {
28
30
  readonly change: TChangeset;
29
31
  /** An identifier representing the session/user/client that made this commit */
30
32
  readonly sessionId: SessionId;
33
+ /** Arbitrary, application-defined metadata stored alongside this commit */
34
+ readonly customMetadata: CustomMetadataTree | undefined;
31
35
  }
32
36
 
33
37
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
@@ -35,6 +39,7 @@ export type EncodedCommit<TChangeset> = {
35
39
  readonly revision: EncodedRevisionTag;
36
40
  readonly change: TChangeset;
37
41
  readonly sessionId: SessionId;
42
+ readonly customMetadata?: EncodedCustomMetadataTree;
38
43
  };
39
44
 
40
45
  const noAdditionalProps: ObjectOptions = { additionalProperties: false };
@@ -42,18 +47,27 @@ const noAdditionalProps: ObjectOptions = { additionalProperties: false };
42
47
  // Many of the return types in this module are intentionally derived, rather than explicitly specified.
43
48
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
44
49
 
45
- const CommitBase = <ChangeSchema extends TSchema>(tChange: ChangeSchema) =>
50
+ const CommitBase = <ChangeSchema extends TSchema>(
51
+ tChange: ChangeSchema,
52
+ includeCustomMetadata: boolean,
53
+ ) =>
46
54
  Type.Object({
47
55
  revision: RevisionTagSchema,
48
56
  change: tChange,
49
57
  sessionId: SessionIdSchema,
58
+ ...(includeCustomMetadata
59
+ ? { customMetadata: Type.Optional(EncodedCustomMetadataTree) }
60
+ : {}),
50
61
  });
62
+
51
63
  /**
52
64
  * @privateRemarks Commits are generally encoded from `GraphCommit`s, which often contain extra data.
53
65
  * This `noAdditionalProps` is especially important in that light.
54
66
  */
55
- const Commit = <ChangeSchema extends TSchema>(tChange: ChangeSchema) =>
56
- Type.Composite([CommitBase(tChange)], noAdditionalProps);
67
+ const Commit = <ChangeSchema extends TSchema>(
68
+ tChange: ChangeSchema,
69
+ includeCustomMetadata: boolean,
70
+ ) => Type.Composite([CommitBase(tChange, includeCustomMetadata)], noAdditionalProps);
57
71
 
58
72
  export type SeqNumber = Brand<number, "edit-manager.SeqNumber">;
59
73
  const SeqNumber = brandedNumberType<SeqNumber>({ multipleOf: 1 });
@@ -70,8 +84,14 @@ export type SequenceId = Static<typeof SequenceId>;
70
84
  */
71
85
  export interface SequencedCommit<TChangeset> extends Commit<TChangeset>, SequenceId {}
72
86
 
73
- export const SequencedCommit = <ChangeSchema extends TSchema>(tChange: ChangeSchema) =>
74
- Type.Composite([CommitBase(tChange), SequenceId], noAdditionalProps);
87
+ /** The persisted counterpart of {@link SequencedCommit}. */
88
+ export type EncodedSequencedCommit<TChangeset> = EncodedCommit<TChangeset> & SequenceId;
89
+
90
+ export const SequencedCommit = <ChangeSchema extends TSchema>(
91
+ tChange: ChangeSchema,
92
+ includeCustomMetadata: boolean,
93
+ ) =>
94
+ Type.Composite([CommitBase(tChange, includeCustomMetadata), SequenceId], noAdditionalProps);
75
95
 
76
96
  /**
77
97
  * A branch off of the trunk for use in summaries.
@@ -86,14 +106,17 @@ export interface SummarySessionBranch<TChangeset> {
86
106
 
87
107
  export interface EncodedSummarySessionBranch<TChangeset> {
88
108
  readonly base: EncodedRevisionTag;
89
- readonly commits: Commit<TChangeset>[];
109
+ readonly commits: EncodedCommit<TChangeset>[];
90
110
  }
91
111
 
92
- export const SummarySessionBranch = <ChangeSchema extends TSchema>(tChange: ChangeSchema) =>
112
+ export const SummarySessionBranch = <ChangeSchema extends TSchema>(
113
+ tChange: ChangeSchema,
114
+ includeCustomMetadata: boolean,
115
+ ) =>
93
116
  Type.Object(
94
117
  {
95
118
  base: RevisionTagSchema,
96
- commits: Type.Array(Commit(tChange)),
119
+ commits: Type.Array(Commit(tChange, includeCustomMetadata)),
97
120
  },
98
121
  noAdditionalProps,
99
122
  );
@@ -104,11 +127,14 @@ export interface EncodedSharedBranch<TChangeset> {
104
127
  readonly author?: string;
105
128
  readonly session?: SessionId;
106
129
  readonly base?: EncodedRevisionTag;
107
- readonly trunk: readonly Readonly<SequencedCommit<TChangeset>>[];
130
+ readonly trunk: readonly Readonly<EncodedSequencedCommit<TChangeset>>[];
108
131
  readonly peers: readonly [SessionId, Readonly<EncodedSummarySessionBranch<TChangeset>>][];
109
132
  }
110
133
 
111
- export const EncodedSharedBranch = <ChangeSchema extends TSchema>(tChange: ChangeSchema) =>
134
+ export const EncodedSharedBranch = <ChangeSchema extends TSchema>(
135
+ tChange: ChangeSchema,
136
+ includeCustomMetadata: boolean,
137
+ ) =>
112
138
  Type.Object(
113
139
  {
114
140
  id: Type.Optional(Type.Number()),
@@ -116,8 +142,10 @@ export const EncodedSharedBranch = <ChangeSchema extends TSchema>(tChange: Chang
116
142
  session: Type.Optional(SessionIdSchema),
117
143
  author: Type.Optional(Type.String()),
118
144
  base: Type.Optional(RevisionTagSchema),
119
- trunk: Type.Array(SequencedCommit(tChange)),
120
- peers: Type.Array(Type.Tuple([SessionIdSchema, SummarySessionBranch(tChange)])),
145
+ trunk: Type.Array(SequencedCommit(tChange, includeCustomMetadata)),
146
+ peers: Type.Array(
147
+ Type.Tuple([SessionIdSchema, SummarySessionBranch(tChange, includeCustomMetadata)]),
148
+ ),
121
149
  },
122
150
  noAdditionalProps,
123
151
  );
@@ -163,6 +191,11 @@ export const EditManagerFormatVersion = strictEnum("editManager.FormatVersion",
163
191
  * Adds support for "no change" constraints.
164
192
  */
165
193
  v6: 6,
194
+ /**
195
+ * Introduced and made available for writing in 2.117.0.
196
+ * Adds support for {@link GraphCommit.customMetadata | persisted commit metadata}.
197
+ */
198
+ v7: 7,
166
199
  /**
167
200
  * Not yet released.
168
201
  * Only used for testing shared branches.
@@ -175,6 +208,7 @@ export const supportedEditManagerFormatVersions: ReadonlySet<EditManagerFormatVe
175
208
  EditManagerFormatVersion.v3,
176
209
  EditManagerFormatVersion.v4,
177
210
  EditManagerFormatVersion.v6,
211
+ EditManagerFormatVersion.v7,
178
212
  EditManagerFormatVersion.vSharedBranches,
179
213
  ]);
180
214
  export const editManagerFormatVersions: ReadonlySet<EditManagerFormatVersion> = new Set(