@fluidframework/tree 2.81.1 → 2.83.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 (695) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/README.md +33 -5
  3. package/api-report/tree.alpha.api.md +75 -39
  4. package/api-report/tree.beta.api.md +164 -3
  5. package/api-report/tree.legacy.beta.api.md +164 -3
  6. package/api-report/tree.legacy.public.api.md +2 -1
  7. package/api-report/tree.public.api.md +2 -1
  8. package/dist/alpha.d.ts +10 -4
  9. package/dist/beta.d.ts +4 -0
  10. package/dist/codec/codec.d.ts +18 -45
  11. package/dist/codec/codec.d.ts.map +1 -1
  12. package/dist/codec/codec.js +12 -50
  13. package/dist/codec/codec.js.map +1 -1
  14. package/dist/codec/index.d.ts +1 -1
  15. package/dist/codec/index.d.ts.map +1 -1
  16. package/dist/codec/index.js +2 -2
  17. package/dist/codec/index.js.map +1 -1
  18. package/dist/codec/versioned/codec.d.ts +20 -7
  19. package/dist/codec/versioned/codec.d.ts.map +1 -1
  20. package/dist/codec/versioned/codec.js +56 -30
  21. package/dist/codec/versioned/codec.js.map +1 -1
  22. package/dist/core/index.d.ts +1 -1
  23. package/dist/core/index.d.ts.map +1 -1
  24. package/dist/core/index.js +4 -2
  25. package/dist/core/index.js.map +1 -1
  26. package/dist/core/rebase/changeRebaser.d.ts +3 -2
  27. package/dist/core/rebase/changeRebaser.d.ts.map +1 -1
  28. package/dist/core/rebase/changeRebaser.js.map +1 -1
  29. package/dist/core/rebase/index.d.ts +1 -1
  30. package/dist/core/rebase/index.d.ts.map +1 -1
  31. package/dist/core/rebase/index.js +4 -2
  32. package/dist/core/rebase/index.js.map +1 -1
  33. package/dist/core/rebase/types.d.ts +23 -3
  34. package/dist/core/rebase/types.d.ts.map +1 -1
  35. package/dist/core/rebase/types.js +30 -16
  36. package/dist/core/rebase/types.js.map +1 -1
  37. package/dist/core/schema-stored/formatV1.d.ts +2 -2
  38. package/dist/core/schema-stored/formatV1.d.ts.map +1 -1
  39. package/dist/core/schema-stored/formatV1.js +0 -5
  40. package/dist/core/schema-stored/formatV1.js.map +1 -1
  41. package/dist/core/schema-stored/formatV2.d.ts +11 -10
  42. package/dist/core/schema-stored/formatV2.d.ts.map +1 -1
  43. package/dist/core/schema-stored/formatV2.js +1 -6
  44. package/dist/core/schema-stored/formatV2.js.map +1 -1
  45. package/dist/core/schema-stored/index.d.ts.map +1 -1
  46. package/dist/core/schema-stored/index.js.map +1 -1
  47. package/dist/core/schema-stored/schema.d.ts.map +1 -1
  48. package/dist/core/schema-stored/schema.js.map +1 -1
  49. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  50. package/dist/core/tree/anchorSet.js.map +1 -1
  51. package/dist/core/tree/delta.d.ts +9 -7
  52. package/dist/core/tree/delta.d.ts.map +1 -1
  53. package/dist/core/tree/delta.js.map +1 -1
  54. package/dist/core/tree/deltaUtil.js +1 -1
  55. package/dist/core/tree/deltaUtil.js.map +1 -1
  56. package/dist/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
  57. package/dist/core/tree/detachedFieldIndexCodecs.js +6 -4
  58. package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
  59. package/dist/core/tree/visitDelta.js +2 -2
  60. package/dist/core/tree/visitDelta.js.map +1 -1
  61. package/dist/extensibleUnionNode.d.ts +97 -0
  62. package/dist/extensibleUnionNode.d.ts.map +1 -0
  63. package/dist/extensibleUnionNode.js +89 -0
  64. package/dist/extensibleUnionNode.js.map +1 -0
  65. package/dist/feature-libraries/changeAtomIdBTree.d.ts +4 -2
  66. package/dist/feature-libraries/changeAtomIdBTree.d.ts.map +1 -1
  67. package/dist/feature-libraries/changeAtomIdBTree.js +9 -1
  68. package/dist/feature-libraries/changeAtomIdBTree.js.map +1 -1
  69. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +1 -1
  70. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  71. package/dist/feature-libraries/chunked-forest/codec/codecs.js +4 -4
  72. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  73. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -3
  74. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  75. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +20 -21
  76. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  77. package/dist/feature-libraries/default-schema/index.d.ts +1 -1
  78. package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
  79. package/dist/feature-libraries/default-schema/index.js.map +1 -1
  80. package/dist/feature-libraries/forest-summary/codec.d.ts +2 -1
  81. package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  82. package/dist/feature-libraries/forest-summary/codec.js +7 -1
  83. package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
  84. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  85. package/dist/feature-libraries/forest-summary/forestSummarizer.js +5 -2
  86. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  87. package/dist/feature-libraries/forest-summary/formatCommon.d.ts +4 -42
  88. package/dist/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
  89. package/dist/feature-libraries/forest-summary/formatCommon.js +1 -2
  90. package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
  91. package/dist/feature-libraries/forest-summary/formatV1.d.ts +2 -41
  92. package/dist/feature-libraries/forest-summary/formatV1.d.ts.map +1 -1
  93. package/dist/feature-libraries/forest-summary/formatV1.js +1 -2
  94. package/dist/feature-libraries/forest-summary/formatV1.js.map +1 -1
  95. package/dist/feature-libraries/forest-summary/formatV2.d.ts +2 -41
  96. package/dist/feature-libraries/forest-summary/formatV2.d.ts.map +1 -1
  97. package/dist/feature-libraries/forest-summary/formatV2.js +1 -2
  98. package/dist/feature-libraries/forest-summary/formatV2.js.map +1 -1
  99. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
  100. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  101. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +1 -1
  102. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  103. package/dist/feature-libraries/index.d.ts +3 -3
  104. package/dist/feature-libraries/index.d.ts.map +1 -1
  105. package/dist/feature-libraries/index.js +4 -3
  106. package/dist/feature-libraries/index.js.map +1 -1
  107. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +2 -2
  108. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -1
  109. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js +42 -22
  110. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -1
  111. package/dist/feature-libraries/modular-schema/genericFieldKind.js +1 -1
  112. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  113. package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
  114. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  115. package/dist/feature-libraries/modular-schema/index.js +2 -1
  116. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  117. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +3 -3
  118. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
  119. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +13 -9
  120. package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
  121. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +11 -1
  122. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  123. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +30 -7
  124. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  125. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  126. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +38 -27
  127. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  128. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +10 -127
  129. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
  130. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -4
  131. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
  132. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +3 -79
  133. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
  134. package/dist/feature-libraries/optional-field/optionalField.js +1 -1
  135. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  136. package/dist/feature-libraries/optional-field/requiredField.d.ts.map +1 -1
  137. package/dist/feature-libraries/optional-field/requiredField.js.map +1 -1
  138. package/dist/feature-libraries/schema-edits/schemaChangeFormat.d.ts +2 -2
  139. package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
  140. package/dist/feature-libraries/schema-index/codec.js +6 -4
  141. package/dist/feature-libraries/schema-index/codec.js.map +1 -1
  142. package/dist/feature-libraries/schema-index/formatV2.d.ts +4 -4
  143. package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -1
  144. package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  145. package/dist/feature-libraries/sequence-field/invert.js +2 -2
  146. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  147. package/dist/feature-libraries/sequence-field/replaceRevisions.js +16 -16
  148. package/dist/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
  149. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +1 -1
  150. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  151. package/dist/index.d.ts +5 -5
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +5 -2
  154. package/dist/index.js.map +1 -1
  155. package/dist/legacy.d.ts +4 -0
  156. package/dist/packageVersion.d.ts +1 -1
  157. package/dist/packageVersion.js +1 -1
  158. package/dist/packageVersion.js.map +1 -1
  159. package/dist/shared-tree/independentView.d.ts +36 -13
  160. package/dist/shared-tree/independentView.d.ts.map +1 -1
  161. package/dist/shared-tree/independentView.js +1 -0
  162. package/dist/shared-tree/independentView.js.map +1 -1
  163. package/dist/shared-tree/index.d.ts +1 -1
  164. package/dist/shared-tree/index.d.ts.map +1 -1
  165. package/dist/shared-tree/index.js.map +1 -1
  166. package/dist/shared-tree/schematizingTreeView.d.ts +10 -0
  167. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  168. package/dist/shared-tree/schematizingTreeView.js +25 -9
  169. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  170. package/dist/shared-tree/sharedTree.d.ts +3 -3
  171. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  172. package/dist/shared-tree/sharedTree.js +8 -32
  173. package/dist/shared-tree/sharedTree.js.map +1 -1
  174. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +11 -3
  175. package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  176. package/dist/shared-tree/sharedTreeChangeCodecs.js +39 -5
  177. package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  178. package/dist/shared-tree/sharedTreeChangeFormat.d.ts +4 -4
  179. package/dist/shared-tree/tree.d.ts +1 -1
  180. package/dist/shared-tree/tree.js +1 -1
  181. package/dist/shared-tree/tree.js.map +1 -1
  182. package/dist/shared-tree/treeAlpha.d.ts +1 -1
  183. package/dist/shared-tree/treeAlpha.js.map +1 -1
  184. package/dist/shared-tree/treeCheckout.d.ts +20 -0
  185. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  186. package/dist/shared-tree/treeCheckout.js +41 -7
  187. package/dist/shared-tree/treeCheckout.js.map +1 -1
  188. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +3 -3
  189. package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  190. package/dist/shared-tree-core/editManagerCodecsCommons.js +2 -2
  191. package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  192. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts +2 -2
  193. package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  194. package/dist/shared-tree-core/editManagerCodecsV1toV4.js +1 -1
  195. package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  196. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +2 -2
  197. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  198. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js +1 -1
  199. package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  200. package/dist/shared-tree-core/editManagerSummarizer.js +1 -1
  201. package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
  202. package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  203. package/dist/shared-tree-core/messageCodecV1ToV4.js +2 -2
  204. package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  205. package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
  206. package/dist/shared-tree-core/messageCodecs.js +2 -2
  207. package/dist/shared-tree-core/messageCodecs.js.map +1 -1
  208. package/dist/shared-tree-core/transaction.d.ts +14 -3
  209. package/dist/shared-tree-core/transaction.d.ts.map +1 -1
  210. package/dist/shared-tree-core/transaction.js +59 -16
  211. package/dist/shared-tree-core/transaction.js.map +1 -1
  212. package/dist/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
  213. package/dist/shared-tree-core/versionedSummarizer.js +1 -1
  214. package/dist/shared-tree-core/versionedSummarizer.js.map +1 -1
  215. package/dist/simple-tree/api/index.d.ts +2 -2
  216. package/dist/simple-tree/api/index.d.ts.map +1 -1
  217. package/dist/simple-tree/api/index.js +4 -3
  218. package/dist/simple-tree/api/index.js.map +1 -1
  219. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +9 -0
  220. package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  221. package/dist/simple-tree/api/schemaCreationUtilities.js +16 -1
  222. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  223. package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
  224. package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts +148 -29
  225. package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
  226. package/dist/simple-tree/api/snapshotCompatibilityChecker.js +180 -99
  227. package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  228. package/dist/simple-tree/api/transactionTypes.d.ts +10 -0
  229. package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
  230. package/dist/simple-tree/api/transactionTypes.js.map +1 -1
  231. package/dist/simple-tree/api/tree.d.ts +82 -7
  232. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  233. package/dist/simple-tree/api/tree.js.map +1 -1
  234. package/dist/simple-tree/api/treeBeta.d.ts +1 -1
  235. package/dist/simple-tree/api/treeBeta.js.map +1 -1
  236. package/dist/simple-tree/core/allowedTypes.d.ts +1 -1
  237. package/dist/simple-tree/core/allowedTypes.js.map +1 -1
  238. package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  239. package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
  240. package/dist/simple-tree/core/unhydratedFlexTree.d.ts +1 -0
  241. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  242. package/dist/simple-tree/core/unhydratedFlexTree.js +29 -0
  243. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  244. package/dist/simple-tree/index.d.ts +2 -2
  245. package/dist/simple-tree/index.d.ts.map +1 -1
  246. package/dist/simple-tree/index.js +5 -3
  247. package/dist/simple-tree/index.js.map +1 -1
  248. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  249. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  250. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts +63 -0
  251. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  252. package/dist/simple-tree/node-kinds/array/arrayNode.js +47 -14
  253. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  254. package/dist/simple-tree/node-kinds/array/index.d.ts +1 -1
  255. package/dist/simple-tree/node-kinds/array/index.d.ts.map +1 -1
  256. package/dist/simple-tree/node-kinds/array/index.js +2 -1
  257. package/dist/simple-tree/node-kinds/array/index.js.map +1 -1
  258. package/dist/simple-tree/node-kinds/index.d.ts +1 -1
  259. package/dist/simple-tree/node-kinds/index.d.ts.map +1 -1
  260. package/dist/simple-tree/node-kinds/index.js +2 -1
  261. package/dist/simple-tree/node-kinds/index.js.map +1 -1
  262. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  263. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  264. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  265. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +33 -7
  266. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  267. package/dist/tableSchema.d.ts +71 -48
  268. package/dist/tableSchema.d.ts.map +1 -1
  269. package/dist/tableSchema.js +200 -98
  270. package/dist/tableSchema.js.map +1 -1
  271. package/dist/text/textDomainFormatted.d.ts +3 -3
  272. package/dist/text/textDomainFormatted.d.ts.map +1 -1
  273. package/dist/text/textDomainFormatted.js +48 -32
  274. package/dist/text/textDomainFormatted.js.map +1 -1
  275. package/dist/util/bTreeUtils.d.ts +30 -4
  276. package/dist/util/bTreeUtils.d.ts.map +1 -1
  277. package/dist/util/bTreeUtils.js +35 -23
  278. package/dist/util/bTreeUtils.js.map +1 -1
  279. package/dist/util/brand.d.ts.map +1 -1
  280. package/dist/util/brand.js.map +1 -1
  281. package/dist/util/brandedMap.d.ts.map +1 -1
  282. package/dist/util/brandedMap.js.map +1 -1
  283. package/dist/util/breakable.d.ts.map +1 -1
  284. package/dist/util/breakable.js +2 -1
  285. package/dist/util/breakable.js.map +1 -1
  286. package/dist/util/index.d.ts +2 -2
  287. package/dist/util/index.d.ts.map +1 -1
  288. package/dist/util/index.js +6 -3
  289. package/dist/util/index.js.map +1 -1
  290. package/dist/util/opaque.d.ts.map +1 -1
  291. package/dist/util/opaque.js.map +1 -1
  292. package/dist/util/rangeMap.d.ts +3 -2
  293. package/dist/util/rangeMap.d.ts.map +1 -1
  294. package/dist/util/rangeMap.js +12 -7
  295. package/dist/util/rangeMap.js.map +1 -1
  296. package/dist/util/readSnapshotBlob.d.ts +1 -1
  297. package/dist/util/readSnapshotBlob.d.ts.map +1 -1
  298. package/dist/util/readSnapshotBlob.js.map +1 -1
  299. package/dist/util/typeCheck.d.ts.map +1 -1
  300. package/dist/util/typeCheck.js.map +1 -1
  301. package/dist/util/utils.d.ts +20 -16
  302. package/dist/util/utils.d.ts.map +1 -1
  303. package/dist/util/utils.js +49 -17
  304. package/dist/util/utils.js.map +1 -1
  305. package/eslint.config.mts +0 -9
  306. package/lib/alpha.d.ts +10 -4
  307. package/lib/beta.d.ts +4 -0
  308. package/lib/codec/codec.d.ts +18 -45
  309. package/lib/codec/codec.d.ts.map +1 -1
  310. package/lib/codec/codec.js +10 -47
  311. package/lib/codec/codec.js.map +1 -1
  312. package/lib/codec/index.d.ts +1 -1
  313. package/lib/codec/index.d.ts.map +1 -1
  314. package/lib/codec/index.js +1 -1
  315. package/lib/codec/index.js.map +1 -1
  316. package/lib/codec/versioned/codec.d.ts +20 -7
  317. package/lib/codec/versioned/codec.d.ts.map +1 -1
  318. package/lib/codec/versioned/codec.js +59 -33
  319. package/lib/codec/versioned/codec.js.map +1 -1
  320. package/lib/core/index.d.ts +1 -1
  321. package/lib/core/index.d.ts.map +1 -1
  322. package/lib/core/index.js +1 -1
  323. package/lib/core/index.js.map +1 -1
  324. package/lib/core/rebase/changeRebaser.d.ts +3 -2
  325. package/lib/core/rebase/changeRebaser.d.ts.map +1 -1
  326. package/lib/core/rebase/changeRebaser.js.map +1 -1
  327. package/lib/core/rebase/index.d.ts +1 -1
  328. package/lib/core/rebase/index.d.ts.map +1 -1
  329. package/lib/core/rebase/index.js +1 -1
  330. package/lib/core/rebase/index.js.map +1 -1
  331. package/lib/core/rebase/types.d.ts +23 -3
  332. package/lib/core/rebase/types.d.ts.map +1 -1
  333. package/lib/core/rebase/types.js +27 -15
  334. package/lib/core/rebase/types.js.map +1 -1
  335. package/lib/core/schema-stored/formatV1.d.ts +2 -2
  336. package/lib/core/schema-stored/formatV1.d.ts.map +1 -1
  337. package/lib/core/schema-stored/formatV1.js +0 -5
  338. package/lib/core/schema-stored/formatV1.js.map +1 -1
  339. package/lib/core/schema-stored/formatV2.d.ts +11 -10
  340. package/lib/core/schema-stored/formatV2.d.ts.map +1 -1
  341. package/lib/core/schema-stored/formatV2.js +1 -6
  342. package/lib/core/schema-stored/formatV2.js.map +1 -1
  343. package/lib/core/schema-stored/index.d.ts.map +1 -1
  344. package/lib/core/schema-stored/index.js +2 -0
  345. package/lib/core/schema-stored/index.js.map +1 -1
  346. package/lib/core/schema-stored/schema.d.ts.map +1 -1
  347. package/lib/core/schema-stored/schema.js.map +1 -1
  348. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  349. package/lib/core/tree/anchorSet.js.map +1 -1
  350. package/lib/core/tree/delta.d.ts +9 -7
  351. package/lib/core/tree/delta.d.ts.map +1 -1
  352. package/lib/core/tree/delta.js.map +1 -1
  353. package/lib/core/tree/deltaUtil.js +1 -1
  354. package/lib/core/tree/deltaUtil.js.map +1 -1
  355. package/lib/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
  356. package/lib/core/tree/detachedFieldIndexCodecs.js +6 -4
  357. package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
  358. package/lib/core/tree/visitDelta.js +2 -2
  359. package/lib/core/tree/visitDelta.js.map +1 -1
  360. package/lib/extensibleUnionNode.d.ts +97 -0
  361. package/lib/extensibleUnionNode.d.ts.map +1 -0
  362. package/lib/extensibleUnionNode.js +86 -0
  363. package/lib/extensibleUnionNode.js.map +1 -0
  364. package/lib/feature-libraries/changeAtomIdBTree.d.ts +4 -2
  365. package/lib/feature-libraries/changeAtomIdBTree.d.ts.map +1 -1
  366. package/lib/feature-libraries/changeAtomIdBTree.js +7 -0
  367. package/lib/feature-libraries/changeAtomIdBTree.js.map +1 -1
  368. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +1 -1
  369. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  370. package/lib/feature-libraries/chunked-forest/codec/codecs.js +5 -5
  371. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  372. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -3
  373. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  374. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +4 -5
  375. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  376. package/lib/feature-libraries/default-schema/index.d.ts +1 -1
  377. package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
  378. package/lib/feature-libraries/default-schema/index.js.map +1 -1
  379. package/lib/feature-libraries/forest-summary/codec.d.ts +2 -1
  380. package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
  381. package/lib/feature-libraries/forest-summary/codec.js +8 -2
  382. package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
  383. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  384. package/lib/feature-libraries/forest-summary/forestSummarizer.js +6 -3
  385. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  386. package/lib/feature-libraries/forest-summary/formatCommon.d.ts +4 -42
  387. package/lib/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
  388. package/lib/feature-libraries/forest-summary/formatCommon.js +2 -3
  389. package/lib/feature-libraries/forest-summary/formatCommon.js.map +1 -1
  390. package/lib/feature-libraries/forest-summary/formatV1.d.ts +2 -41
  391. package/lib/feature-libraries/forest-summary/formatV1.d.ts.map +1 -1
  392. package/lib/feature-libraries/forest-summary/formatV1.js +1 -2
  393. package/lib/feature-libraries/forest-summary/formatV1.js.map +1 -1
  394. package/lib/feature-libraries/forest-summary/formatV2.d.ts +2 -41
  395. package/lib/feature-libraries/forest-summary/formatV2.d.ts.map +1 -1
  396. package/lib/feature-libraries/forest-summary/formatV2.js +1 -2
  397. package/lib/feature-libraries/forest-summary/formatV2.js.map +1 -1
  398. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
  399. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  400. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +1 -1
  401. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  402. package/lib/feature-libraries/index.d.ts +3 -3
  403. package/lib/feature-libraries/index.d.ts.map +1 -1
  404. package/lib/feature-libraries/index.js +3 -3
  405. package/lib/feature-libraries/index.js.map +1 -1
  406. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +2 -2
  407. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -1
  408. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js +41 -21
  409. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -1
  410. package/lib/feature-libraries/modular-schema/genericFieldKind.js +1 -1
  411. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  412. package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
  413. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  414. package/lib/feature-libraries/modular-schema/index.js +1 -1
  415. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  416. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +3 -3
  417. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
  418. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +14 -10
  419. package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
  420. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +11 -1
  421. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  422. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +29 -6
  423. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  424. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  425. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +41 -30
  426. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  427. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +10 -127
  428. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
  429. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -4
  430. package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
  431. package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +3 -79
  432. package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
  433. package/lib/feature-libraries/optional-field/optionalField.js +1 -1
  434. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  435. package/lib/feature-libraries/optional-field/requiredField.d.ts.map +1 -1
  436. package/lib/feature-libraries/optional-field/requiredField.js.map +1 -1
  437. package/lib/feature-libraries/schema-edits/schemaChangeFormat.d.ts +2 -2
  438. package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
  439. package/lib/feature-libraries/schema-index/codec.js +6 -4
  440. package/lib/feature-libraries/schema-index/codec.js.map +1 -1
  441. package/lib/feature-libraries/schema-index/formatV2.d.ts +4 -4
  442. package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -1
  443. package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  444. package/lib/feature-libraries/sequence-field/invert.js +2 -2
  445. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  446. package/lib/feature-libraries/sequence-field/replaceRevisions.js +16 -16
  447. package/lib/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
  448. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +1 -1
  449. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  450. package/lib/index.d.ts +5 -5
  451. package/lib/index.d.ts.map +1 -1
  452. package/lib/index.js +4 -3
  453. package/lib/index.js.map +1 -1
  454. package/lib/legacy.d.ts +4 -0
  455. package/lib/packageVersion.d.ts +1 -1
  456. package/lib/packageVersion.js +1 -1
  457. package/lib/packageVersion.js.map +1 -1
  458. package/lib/shared-tree/independentView.d.ts +36 -13
  459. package/lib/shared-tree/independentView.d.ts.map +1 -1
  460. package/lib/shared-tree/independentView.js +1 -0
  461. package/lib/shared-tree/independentView.js.map +1 -1
  462. package/lib/shared-tree/index.d.ts +1 -1
  463. package/lib/shared-tree/index.d.ts.map +1 -1
  464. package/lib/shared-tree/index.js.map +1 -1
  465. package/lib/shared-tree/schematizingTreeView.d.ts +10 -0
  466. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  467. package/lib/shared-tree/schematizingTreeView.js +25 -9
  468. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  469. package/lib/shared-tree/sharedTree.d.ts +3 -3
  470. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  471. package/lib/shared-tree/sharedTree.js +10 -34
  472. package/lib/shared-tree/sharedTree.js.map +1 -1
  473. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +11 -3
  474. package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
  475. package/lib/shared-tree/sharedTreeChangeCodecs.js +40 -6
  476. package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
  477. package/lib/shared-tree/sharedTreeChangeFormat.d.ts +4 -4
  478. package/lib/shared-tree/tree.d.ts +1 -1
  479. package/lib/shared-tree/tree.js +1 -1
  480. package/lib/shared-tree/tree.js.map +1 -1
  481. package/lib/shared-tree/treeAlpha.d.ts +1 -1
  482. package/lib/shared-tree/treeAlpha.js.map +1 -1
  483. package/lib/shared-tree/treeCheckout.d.ts +20 -0
  484. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  485. package/lib/shared-tree/treeCheckout.js +41 -7
  486. package/lib/shared-tree/treeCheckout.js.map +1 -1
  487. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +3 -3
  488. package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
  489. package/lib/shared-tree-core/editManagerCodecsCommons.js +2 -2
  490. package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
  491. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts +2 -2
  492. package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
  493. package/lib/shared-tree-core/editManagerCodecsV1toV4.js +2 -2
  494. package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
  495. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +2 -2
  496. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
  497. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js +2 -2
  498. package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
  499. package/lib/shared-tree-core/editManagerSummarizer.js +1 -1
  500. package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
  501. package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
  502. package/lib/shared-tree-core/messageCodecV1ToV4.js +2 -2
  503. package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
  504. package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
  505. package/lib/shared-tree-core/messageCodecs.js +2 -2
  506. package/lib/shared-tree-core/messageCodecs.js.map +1 -1
  507. package/lib/shared-tree-core/transaction.d.ts +14 -3
  508. package/lib/shared-tree-core/transaction.d.ts.map +1 -1
  509. package/lib/shared-tree-core/transaction.js +61 -18
  510. package/lib/shared-tree-core/transaction.js.map +1 -1
  511. package/lib/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
  512. package/lib/shared-tree-core/versionedSummarizer.js +1 -1
  513. package/lib/shared-tree-core/versionedSummarizer.js.map +1 -1
  514. package/lib/simple-tree/api/index.d.ts +2 -2
  515. package/lib/simple-tree/api/index.d.ts.map +1 -1
  516. package/lib/simple-tree/api/index.js +2 -2
  517. package/lib/simple-tree/api/index.js.map +1 -1
  518. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +9 -0
  519. package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  520. package/lib/simple-tree/api/schemaCreationUtilities.js +14 -0
  521. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  522. package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
  523. package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts +148 -29
  524. package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
  525. package/lib/simple-tree/api/snapshotCompatibilityChecker.js +179 -98
  526. package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  527. package/lib/simple-tree/api/transactionTypes.d.ts +10 -0
  528. package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
  529. package/lib/simple-tree/api/transactionTypes.js.map +1 -1
  530. package/lib/simple-tree/api/tree.d.ts +82 -7
  531. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  532. package/lib/simple-tree/api/tree.js.map +1 -1
  533. package/lib/simple-tree/api/treeBeta.d.ts +1 -1
  534. package/lib/simple-tree/api/treeBeta.js.map +1 -1
  535. package/lib/simple-tree/core/allowedTypes.d.ts +1 -1
  536. package/lib/simple-tree/core/allowedTypes.js.map +1 -1
  537. package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  538. package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
  539. package/lib/simple-tree/core/unhydratedFlexTree.d.ts +1 -0
  540. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  541. package/lib/simple-tree/core/unhydratedFlexTree.js +29 -0
  542. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  543. package/lib/simple-tree/index.d.ts +2 -2
  544. package/lib/simple-tree/index.d.ts.map +1 -1
  545. package/lib/simple-tree/index.js +2 -2
  546. package/lib/simple-tree/index.js.map +1 -1
  547. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  548. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  549. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts +63 -0
  550. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  551. package/lib/simple-tree/node-kinds/array/arrayNode.js +46 -14
  552. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  553. package/lib/simple-tree/node-kinds/array/index.d.ts +1 -1
  554. package/lib/simple-tree/node-kinds/array/index.d.ts.map +1 -1
  555. package/lib/simple-tree/node-kinds/array/index.js +1 -1
  556. package/lib/simple-tree/node-kinds/array/index.js.map +1 -1
  557. package/lib/simple-tree/node-kinds/index.d.ts +1 -1
  558. package/lib/simple-tree/node-kinds/index.d.ts.map +1 -1
  559. package/lib/simple-tree/node-kinds/index.js +1 -1
  560. package/lib/simple-tree/node-kinds/index.js.map +1 -1
  561. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  562. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  563. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  564. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +34 -8
  565. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  566. package/lib/tableSchema.d.ts +71 -48
  567. package/lib/tableSchema.d.ts.map +1 -1
  568. package/lib/tableSchema.js +201 -99
  569. package/lib/tableSchema.js.map +1 -1
  570. package/lib/text/textDomainFormatted.d.ts +3 -3
  571. package/lib/text/textDomainFormatted.d.ts.map +1 -1
  572. package/lib/text/textDomainFormatted.js +30 -14
  573. package/lib/text/textDomainFormatted.js.map +1 -1
  574. package/lib/util/bTreeUtils.d.ts +30 -4
  575. package/lib/util/bTreeUtils.d.ts.map +1 -1
  576. package/lib/util/bTreeUtils.js +33 -22
  577. package/lib/util/bTreeUtils.js.map +1 -1
  578. package/lib/util/brand.d.ts.map +1 -1
  579. package/lib/util/brand.js.map +1 -1
  580. package/lib/util/brandedMap.d.ts.map +1 -1
  581. package/lib/util/brandedMap.js.map +1 -1
  582. package/lib/util/breakable.d.ts.map +1 -1
  583. package/lib/util/breakable.js +2 -1
  584. package/lib/util/breakable.js.map +1 -1
  585. package/lib/util/index.d.ts +2 -2
  586. package/lib/util/index.d.ts.map +1 -1
  587. package/lib/util/index.js +2 -2
  588. package/lib/util/index.js.map +1 -1
  589. package/lib/util/opaque.d.ts.map +1 -1
  590. package/lib/util/opaque.js.map +1 -1
  591. package/lib/util/rangeMap.d.ts +3 -2
  592. package/lib/util/rangeMap.d.ts.map +1 -1
  593. package/lib/util/rangeMap.js +12 -7
  594. package/lib/util/rangeMap.js.map +1 -1
  595. package/lib/util/readSnapshotBlob.d.ts +1 -1
  596. package/lib/util/readSnapshotBlob.d.ts.map +1 -1
  597. package/lib/util/readSnapshotBlob.js.map +1 -1
  598. package/lib/util/typeCheck.d.ts.map +1 -1
  599. package/lib/util/typeCheck.js.map +1 -1
  600. package/lib/util/utils.d.ts +20 -16
  601. package/lib/util/utils.d.ts.map +1 -1
  602. package/lib/util/utils.js +44 -15
  603. package/lib/util/utils.js.map +1 -1
  604. package/package.json +24 -24
  605. package/src/codec/codec.ts +33 -116
  606. package/src/codec/index.ts +2 -3
  607. package/src/codec/versioned/codec.ts +127 -95
  608. package/src/core/index.ts +3 -1
  609. package/src/core/rebase/changeRebaser.ts +3 -2
  610. package/src/core/rebase/index.ts +3 -1
  611. package/src/core/rebase/types.ts +51 -13
  612. package/src/core/schema-stored/formatV1.ts +2 -4
  613. package/src/core/schema-stored/formatV2.ts +9 -7
  614. package/src/core/schema-stored/index.ts +2 -0
  615. package/src/core/schema-stored/schema.ts +4 -1
  616. package/src/core/tree/anchorSet.ts +1 -3
  617. package/src/core/tree/delta.ts +9 -7
  618. package/src/core/tree/deltaUtil.ts +1 -1
  619. package/src/core/tree/detachedFieldIndexCodecs.ts +6 -4
  620. package/src/core/tree/visitDelta.ts +2 -2
  621. package/src/extensibleUnionNode.ts +177 -0
  622. package/src/feature-libraries/changeAtomIdBTree.ts +17 -2
  623. package/src/feature-libraries/chunked-forest/codec/codecs.ts +5 -11
  624. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +5 -6
  625. package/src/feature-libraries/default-schema/index.ts +0 -1
  626. package/src/feature-libraries/forest-summary/codec.ts +15 -9
  627. package/src/feature-libraries/forest-summary/forestSummarizer.ts +15 -3
  628. package/src/feature-libraries/forest-summary/formatCommon.ts +7 -6
  629. package/src/feature-libraries/forest-summary/formatV1.ts +1 -3
  630. package/src/feature-libraries/forest-summary/formatV2.ts +1 -3
  631. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +4 -5
  632. package/src/feature-libraries/index.ts +3 -2
  633. package/src/feature-libraries/modular-schema/defaultRevisionReplacer.ts +57 -31
  634. package/src/feature-libraries/modular-schema/genericFieldKind.ts +1 -1
  635. package/src/feature-libraries/modular-schema/index.ts +4 -1
  636. package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +12 -12
  637. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +32 -7
  638. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +54 -33
  639. package/src/feature-libraries/modular-schema/modularChangeFormatV1.ts +2 -4
  640. package/src/feature-libraries/optional-field/optionalField.ts +1 -1
  641. package/src/feature-libraries/optional-field/requiredField.ts +2 -4
  642. package/src/feature-libraries/schema-index/codec.ts +7 -5
  643. package/src/feature-libraries/schema-index/schemaSummarizer.ts +1 -1
  644. package/src/feature-libraries/sequence-field/invert.ts +2 -2
  645. package/src/feature-libraries/sequence-field/replaceRevisions.ts +17 -10
  646. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +1 -1
  647. package/src/index.ts +14 -9
  648. package/src/packageVersion.ts +1 -1
  649. package/src/shared-tree/independentView.ts +42 -6
  650. package/src/shared-tree/index.ts +2 -0
  651. package/src/shared-tree/schematizingTreeView.ts +63 -18
  652. package/src/shared-tree/sharedTree.ts +19 -37
  653. package/src/shared-tree/sharedTreeChangeCodecs.ts +45 -11
  654. package/src/shared-tree/tree.ts +2 -2
  655. package/src/shared-tree/treeAlpha.ts +1 -1
  656. package/src/shared-tree/treeCheckout.ts +52 -7
  657. package/src/shared-tree-core/editManagerCodecsCommons.ts +7 -7
  658. package/src/shared-tree-core/editManagerCodecsV1toV4.ts +3 -10
  659. package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +3 -10
  660. package/src/shared-tree-core/editManagerSummarizer.ts +1 -1
  661. package/src/shared-tree-core/messageCodecV1ToV4.ts +4 -3
  662. package/src/shared-tree-core/messageCodecs.ts +2 -6
  663. package/src/shared-tree-core/transaction.ts +125 -23
  664. package/src/shared-tree-core/versionedSummarizer.ts +3 -2
  665. package/src/simple-tree/api/index.ts +3 -2
  666. package/src/simple-tree/api/schemaCreationUtilities.ts +35 -5
  667. package/src/simple-tree/api/simpleTreeIndex.ts +1 -1
  668. package/src/simple-tree/api/snapshotCompatibilityChecker.ts +344 -142
  669. package/src/simple-tree/api/transactionTypes.ts +10 -0
  670. package/src/simple-tree/api/tree.ts +89 -7
  671. package/src/simple-tree/api/treeBeta.ts +1 -1
  672. package/src/simple-tree/core/allowedTypes.ts +1 -1
  673. package/src/simple-tree/core/treeNodeSchema.ts +5 -8
  674. package/src/simple-tree/core/unhydratedFlexTree.ts +43 -1
  675. package/src/simple-tree/index.ts +5 -2
  676. package/src/simple-tree/leafNodeSchema.ts +3 -2
  677. package/src/simple-tree/node-kinds/array/arrayNode.ts +99 -19
  678. package/src/simple-tree/node-kinds/array/index.ts +2 -0
  679. package/src/simple-tree/node-kinds/index.ts +2 -0
  680. package/src/simple-tree/node-kinds/object/objectNode.ts +19 -18
  681. package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +51 -10
  682. package/src/tableSchema.ts +280 -140
  683. package/src/text/textDomainFormatted.ts +37 -17
  684. package/src/util/bTreeUtils.ts +55 -32
  685. package/src/util/brand.ts +4 -12
  686. package/src/util/brandedMap.ts +2 -6
  687. package/src/util/breakable.ts +3 -2
  688. package/src/util/index.ts +9 -3
  689. package/src/util/opaque.ts +2 -6
  690. package/src/util/rangeMap.ts +20 -11
  691. package/src/util/readSnapshotBlob.ts +3 -3
  692. package/src/util/typeCheck.ts +11 -9
  693. package/src/util/utils.ts +57 -28
  694. package/api-extractor-lint.json +0 -4
  695. package/biome.jsonc +0 -4
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { assert, transformMapValues } from "@fluidframework/core-utils/internal";
6
+ import { assert, fail, transformMapValues } from "@fluidframework/core-utils/internal";
7
7
  import { selectVersionRoundedDown } from "@fluidframework/runtime-utils/internal";
8
8
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
9
9
  import * as semver from "semver-ts";
@@ -149,7 +149,7 @@ export function importCompatibilitySchemaSnapshot(
149
149
  }
150
150
 
151
151
  /**
152
- * The file system methods required by {@link checkSchemaCompatibilitySnapshots}.
152
+ * The file system methods required by {@link snapshotSchemaCompatibility}.
153
153
  * @remarks
154
154
  * Implemented by both Node.js `fs` and `path` modules, but other implementations can be provided as needed.
155
155
  *
@@ -227,36 +227,83 @@ export interface CombinedSchemaCompatibilityStatus {
227
227
  * How a {@link TreeView} using the snapshotted schema would report its compatibility with a document created with the current schema.
228
228
  */
229
229
  readonly snapshotViewOfCurrentDocument: Omit<SchemaCompatibilityStatus, "canInitialize">;
230
+
231
+ /**
232
+ * True if and only if the schema have identical compatibility.
233
+ * @remarks
234
+ * This includes producing the equivalent stored schema (which currentViewOfSnapshotDocument and snapshotViewOfCurrentDocument also measure)
235
+ * as well as equivalent compatibility with potential future schema changes beyond just those in these two schema.
236
+ *
237
+ * This includes compatibility with all potential future schema changes.
238
+ * For example two schema different only in compatibility with future optional fields via allow unknown optional fields or staged schema
239
+ * would be considered non-equivalent, even though they are forwards and backwards compatible with each other, and both status above report them as equivalent
240
+ * since they would produce the same stored schema upon schema upgrade.
241
+ */
242
+ readonly identicalCompatibility: boolean;
230
243
  }
231
244
 
232
245
  /**
233
- * The options for {@link checkSchemaCompatibilitySnapshots}.
246
+ * The options for {@link snapshotSchemaCompatibility}.
234
247
  * @input
235
248
  * @alpha
236
249
  */
237
- export interface SchemaCompatibilitySnapshotsOptions {
250
+ export interface SnapshotSchemaCompatibilityOptions {
238
251
  /**
239
252
  * Directory where historical schema snapshots are stored.
253
+ * @remarks
254
+ * As the contents of this directory (specifically historical snapshots) cannot be regenerated,
255
+ * a directory appropriate for test data should be used.
256
+ * Generally this means that this directory should be versioned like code,
257
+ * and not erased when regenerating snapshots.
258
+ *
259
+ * This directory will be created if it does not already exist.
260
+ * All ".json" files in this directory will be treated as schema snapshots.
261
+ * It is recommended to use a dedicated directory for each {@link snapshotSchemaCompatibility} powered test.
262
+ *
263
+ * This can use any path syntax supported by the provided {@link SnapshotSchemaCompatibilityOptions.fileSystem}.
240
264
  */
241
265
  readonly snapshotDirectory: string;
266
+
242
267
  /**
243
268
  * How the `snapshotDirectory` is accessed.
244
269
  */
245
270
  readonly fileSystem: SnapshotFileSystem;
246
- /**
247
- * The current application or library version.
248
- * @remarks
249
- * This uses the {@link https://semver.org/#spec-item-11|ordering defined by semver}.
250
- * It is only compared against the version from previous snapshots (taken from this version when they were created by setting `mode` to "update") and the `minVersionForCollaboration`.
251
- */
252
- readonly version: string;
271
+
253
272
  /**
254
273
  * The current view schema.
255
274
  */
256
275
  readonly schema: TreeViewConfiguration;
276
+
277
+ /**
278
+ * The version which will be associated with this version of the schema.
279
+ * @remarks
280
+ * Often the easiest way to ensure this is to simply use the next version which will be released for the package or application itself, and set the `minVersionForCollaboration` based on telemetry about which versions are still in use.
281
+ * To do this, it is recommended that this version be programmatically derived from the application version rather than hard coded inline.
282
+ * For example, reading it from the `package.json` or some other source of truth can be done to ensure it is kept up to date, and thus snapshots always have the correct version.
283
+ * The version used should typically be the _next_ production version (whose formats must be supported long term) that will be released (but is not yet released).
284
+ * This usually means that the correct version to use is the same version that would be used when releasing the application or library, but with any prerelease version tags removed.
285
+ * If an automated way to keep this version up to date is not used, be very careful when reviewing changes to snapshot files to ensure the version is correct.
286
+ * If incorrectly versioned snapshots were committed accidentally, rename the snapshot files to have the correct version, and restore the old files from, version control.
287
+ *
288
+ * It is possible to use a different versioning scheme, for example one specific to the schema in question.
289
+ * This can be done robustly as long as care is taken to ensure the version increases such that every released version has a unique `version` (and therefore unique snapshot),
290
+ * and `minVersionForCollaboration` is set appropriately using the same versioning scheme.
291
+ * {@link SnapshotSchemaCompatibilityOptions.rejectVersionsWithNoSchemaChange} and
292
+ * {@link SnapshotSchemaCompatibilityOptions.rejectSchemaChangesWithNoVersionChange}
293
+ * can be used to help enforce the expected relationship between version changes and schema changes in such cases.
294
+ *
295
+ * Can use any format supported by {@link SnapshotSchemaCompatibilityOptions.versionComparer}.
296
+ * Only compared against the version from previous snapshots (taken from this version when they were created by setting `mode` to "update") and the `minVersionForCollaboration`.
297
+ *
298
+ * Typically `minVersionForCollaboration` should be set to the oldest version currently in use, so it's helpful to use a version which can be easily measured to tell if clients are still using it.
299
+ */
300
+ readonly version: string;
301
+
257
302
  /**
258
303
  * The minimum version that the current version is expected to be able to collaborate with.
259
304
  * @remarks
305
+ * Can use any format supported by {@link SnapshotSchemaCompatibilityOptions.versionComparer}.
306
+ *
260
307
  * This defines a range of versions whose schema must be forwards compatible with trees using the current schema:
261
308
  * Any schema from snapshots with a version greater than or equal to this must be able to view documents created with the current schema.
262
309
  * This means that if the current `schema` is used to create a {@link TreeView}, then {@link TreeView.upgradeSchema} is used, the older clients,
@@ -265,13 +312,24 @@ export interface SchemaCompatibilitySnapshotsOptions {
265
312
  * Typically applications will attempt to manage their deployment/update schedule such that all versions concurrently deployed can
266
313
  * collaborate to avoid users losing access to documents when other users upgrade the schema.
267
314
  * Such applications can set this to the oldest version currently deployed,
268
- * then rely on {@link checkSchemaCompatibilitySnapshots} to verify that no schema changes are made which would break collaboration with that (or newer) versions.
315
+ * then rely on {@link snapshotSchemaCompatibility} to verify that no schema changes are made which would break collaboration with that (or newer) versions.
269
316
  *
270
317
  * This is the same approach used by {@link @fluidframework/runtime-definitions#MinimumVersionForCollab}
271
318
  * except that type is specifically for use with the version of the Fluid Framework client packages,
272
- * and this corresponds to the version of the application or library defining the schema.
319
+ * and this corresponds to whatever versioning scheme is used with {@link SnapshotSchemaCompatibilityOptions.version}.
273
320
  */
274
321
  readonly minVersionForCollaboration: string;
322
+
323
+ /**
324
+ * A comparison function for version strings.
325
+ * @remarks
326
+ * A comparison function like that provided to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#comparefn | Array.sort}.
327
+ * This is used to partition snapshots into those less than `minVersionForCollaboration` and those greater than or equal to it, as well as to sanity check `version` against the versions of the snapshots.
328
+ * If not provided, the ordering is defined by {@link https://semver.org/#spec-item-11|semver}.
329
+ * @returns A negative number if `a` is less than `b`, zero if they are equal, or a positive number if `a` is greater than `b`.
330
+ */
331
+ readonly versionComparer?: (a: string, b: string) => number;
332
+
275
333
  /**
276
334
  * When true, every version must be snapshotted, and an increased version number will require a new snapshot.
277
335
  * @remarks
@@ -280,26 +338,55 @@ export interface SchemaCompatibilitySnapshotsOptions {
280
338
  * can refer to versions between snapshots and will get its schema from the preceding version.
281
339
  */
282
340
  readonly snapshotUnchangedVersions?: true;
341
+
283
342
  /**
284
- * The mode of operation, either "test" or "update".
343
+ * When true, it is an error if a new a snapshot for a new version would be created, but the schema compatibility is identical to the previous snapshot.
285
344
  * @remarks
286
- * In "update" mode, a new snapshot is created if the current schema differs from the latest existing snapshot.
287
- * Note: {@link SchemaCompatibilitySnapshotsOptions.snapshotUnchangedVersions} impacts this behavior.
345
+ * This prevents creating a snapshot with the same schema compatibility results as the previous one.
288
346
  *
289
- * In "test" mode, an error is thrown if running in "update" mode would have made any changes.
347
+ * Applications and libraries which do not have versioned releases can make up a version specific to the compatibility of the schema, and use this option to help ensure they manage that version correctly.
348
+ * Such cases can also opt into {@link SnapshotSchemaCompatibilityOptions.rejectSchemaChangesWithNoVersionChange} if they want additional strictness.
349
+ */
350
+ readonly rejectVersionsWithNoSchemaChange?: true;
351
+
352
+ /**
353
+ * When true, it is an error if a schema change occurs without a corresponding version change.
354
+ * @remarks
355
+ * This disables overwriting existing snapshots.
356
+ * This option is recommended if the {@link SnapshotSchemaCompatibilityOptions.version} is not automatically updated ahead of releasing a version which must be supported.
357
+ * If updating the snapshot is still desired, the preceding one which needs to be overwritten can be manually deleted before running the update.
290
358
  *
359
+ * This option does not impact the behavior of assert mode (other than impacting what error is given).
360
+ * This option simply makes update mode more strict, converting cases that would overwrite a snapshot in place into errors.
361
+ */
362
+ readonly rejectSchemaChangesWithNoVersionChange?: true;
363
+
364
+ /**
365
+ * The mode of operation, either "assert" or "update".
366
+ * @remarks
291
367
  * Both modes will throw errors if any compatibility issues are detected (but after updating snapshots in "update" mode so the diff can be used to help debug).
292
368
  *
293
- * It is recommended that "test" mode be used in automated tests to verify schema compatibility,
294
- * and "update" mode only be used manually to update snapshots when making schema changes (or version changes if `snapshotUnchangedVersions` is true).
369
+ * In "assert" mode, an error is additionally thrown if the latest snapshot is not up to date (meaning "update" mode would make a change).
370
+ *
371
+ * In "update" mode, a new snapshot is created if the current schema differs from the latest existing snapshot.
372
+ * If {@link SnapshotSchemaCompatibilityOptions.rejectVersionsWithNoSchemaChange} or
373
+ * {@link SnapshotSchemaCompatibilityOptions.rejectSchemaChangesWithNoVersionChange} disallows the update, an error is thrown instead.
374
+ *
375
+ * It is recommended that "assert" mode be used in automated tests to verify schema compatibility,
376
+ * and "update" mode only be used manually to update snapshots when making schema or version changes.
377
+ *
378
+ * @privateRemarks
379
+ * Modes we might want to add in the future:
380
+ * - normalize: update the latest snapshot (or maybe all of them) to the latest encoded format.
381
+ * - some mode like assert but returns information instead of throwing.
295
382
  */
296
- readonly mode: "test" | "update";
383
+ readonly mode: "assert" | "update";
297
384
  }
298
385
 
299
386
  /**
300
387
  * Check `currentViewSchema` for compatibility with a collection of historical schema snapshots stored in `snapshotDirectory`.
301
388
  *
302
- * @throws Throws errors if the input version strings (including those in snapshot file names) are not valid semver versions.
389
+ * @throws Throws errors if the input version strings (including those in snapshot file names) are not valid semver versions when using default semver version comparison.
303
390
  * @throws Throws errors if the input version strings (including those in snapshot file names) are not ordered as expected (current being the highest, and `minVersionForCollaboration` corresponding to the current version or a lower snapshotted version).
304
391
  * @throws In `test` mode, throws an error if there is not an up to date snapshot for the current version.
305
392
  * @throws Throws an error if any snapshotted schema cannot be upgraded to the current schema.
@@ -319,6 +406,14 @@ export interface SchemaCompatibilitySnapshotsOptions {
319
406
  * This is a known limitation that will be improved in future releases.
320
407
  * These improvements, as well as other changes, may change the exact messages produced by this function in the error cases: no stability of these messages should be assumed.
321
408
  *
409
+ * Unlike some other snapshot based testing tools, this stores more than just the current snapshot: historical snapshots are retained as well.
410
+ * Retention of these additional historical snapshots, whose content can't be regenerated from the current schema, is necessary to properly test compatibility across versions.
411
+ * Since there is content in the snapshots which cannot be regenerated, tools which assume all snapshotted content can be regenerated cannot be used here.
412
+ * This means that tools like Jest's built in snapshot testing are not suitable for this purpose.
413
+ * These snapshots behave partly like test data, and partly like snapshots.
414
+ * Typically the easiest way to manage this is to place {@link SnapshotSchemaCompatibilityOptions.snapshotDirectory} inside a directory appropriate for test data,
415
+ * and use node to provide the filesystem access via {@link SnapshotSchemaCompatibilityOptions.fileSystem}.
416
+ *
322
417
  * For now, locating what change broke compatibility is likely best discovered by making small schema changes one at a time and updating the snapshot and reviewing the diffs.
323
418
  * Details for what kinds of changes are breaking and in which ways can be found in the documentation for {@link TreeView.compatibility} and
324
419
  * {@link https://fluidframework.com/docs/data-structures/tree/schema-evolution/ | schema-evolution}.
@@ -337,7 +432,7 @@ export interface SchemaCompatibilitySnapshotsOptions {
337
432
  * @example Mocha test which validates the current `config` can collaborate with all historical version back to 2.0.0, and load and update any versions older than that.
338
433
  * ```typescript
339
434
  * it("schema compatibility", () => {
340
- * checkSchemaCompatibilitySnapshots({
435
+ * snapshotSchemaCompatibility({
341
436
  * version: pkgVersion,
342
437
  * schema: config,
343
438
  * fileSystem: { ...fs, ...path },
@@ -347,19 +442,53 @@ export interface SchemaCompatibilitySnapshotsOptions {
347
442
  * });
348
443
  * });
349
444
  * ```
445
+ * @example Complete Mocha test file
446
+ * ```typescript
447
+ * import fs from "node:fs";
448
+ * import path from "node:path";
449
+ *
450
+ * import { snapshotSchemaCompatibility } from "@fluidframework/tree/alpha";
451
+ *
452
+ * // The TreeViewConfiguration the application uses, which contains the application's schema.
453
+ * import { treeViewConfiguration } from "./schema.js";
454
+ * // The next version of the application which will be released.
455
+ * import { packageVersion } from "./version.js";
456
+ *
457
+ * // Provide some way to run the check in "update" mode when updating snapshots is intended.
458
+ * const regenerateSnapshots = process.argv.includes("--snapshot");
459
+ *
460
+ * // Setup the actual test. In this case using Mocha syntax.
461
+ * describe("schema", () => {
462
+ * it("schema compatibility", () => {
463
+ * // Select a path to save the snapshots in.
464
+ * // This will depend on how your application organizes its test data.
465
+ * const snapshotDirectory = path.join(
466
+ * import.meta.dirname,
467
+ * "../../../src/test/schema-snapshots",
468
+ * );
469
+ * snapshotSchemaCompatibility({
470
+ * schema: config,
471
+ * fileSystem: { ...fs, ...path },
472
+ * version: pkgVersion,
473
+ * minVersionForCollaboration: "2.0.0",
474
+ * mode: process.argv.includes("--snapshot") ? "update" : "assert",
475
+ * snapshotDirectory,
476
+ * });
477
+ * });
478
+ * });
479
+ * ```
350
480
  * @privateRemarks
351
481
  * Use of this function within this package (for schema libraries released as part of this package) should use {@link testSchemaCompatibilitySnapshots} instead.
352
482
  *
353
- * TODO: this uses the format defined in simpleSchemaCodec.ts.
354
- * Currently this does not include any versioning information in the snapshot format itself.
355
- * This would make it hard to do things like upgrade to a new format (perhaps for better diffs, or to support new features) in the future.
356
- * That code should probably be migrated to a proper versioned codec with a schema and validation.
357
- * This utility can directly depend on the typebox-validator and inject that as this code should not be bundle size sensitive.
358
- * This should be addressed before this reached beta stability.
483
+ * This uses the format defined in simpleSchemaCodec.ts.
484
+ * This does include versioning information in the snapshot format,
485
+ * but it would be nice to better unify how we do that versioning and format validation with our codecs.
486
+ *
487
+ * See snapshotCompatibilityChecker.example.mts for the large example included above.
359
488
  * @alpha
360
489
  */
361
- export function checkSchemaCompatibilitySnapshots(
362
- options: SchemaCompatibilitySnapshotsOptions,
490
+ export function snapshotSchemaCompatibility(
491
+ options: SnapshotSchemaCompatibilityOptions,
363
492
  ): void {
364
493
  const checker = new SnapshotCompatibilityChecker(
365
494
  options.snapshotDirectory,
@@ -371,123 +500,191 @@ export function checkSchemaCompatibilitySnapshots(
371
500
  mode,
372
501
  minVersionForCollaboration,
373
502
  snapshotUnchangedVersions,
503
+ rejectVersionsWithNoSchemaChange,
504
+ rejectSchemaChangesWithNoVersionChange,
374
505
  } = options;
375
- if (semver.valid(currentVersion) === null) {
506
+
507
+ const validateVersion =
508
+ options.versionComparer === undefined ? semver.valid : (v: string) => v;
509
+ const versionComparer = options.versionComparer ?? semver.compare;
510
+
511
+ if (validateVersion(currentVersion) === null) {
376
512
  throw new UsageError(
377
513
  `Invalid version: ${JSON.stringify(currentVersion)}. Must be a valid semver version.`,
378
514
  );
379
515
  }
380
- if (semver.valid(minVersionForCollaboration) === null) {
516
+ if (validateVersion(minVersionForCollaboration) === null) {
381
517
  throw new UsageError(
382
518
  `Invalid minVersionForCollaboration: ${JSON.stringify(minVersionForCollaboration)}. Must be a valid semver version.`,
383
519
  );
384
520
  }
385
- if (!semver.lte(minVersionForCollaboration, currentVersion)) {
521
+
522
+ if (versionComparer(minVersionForCollaboration, currentVersion) > 0) {
386
523
  throw new UsageError(
387
524
  `Invalid minVersionForCollaboration: ${JSON.stringify(minVersionForCollaboration)}. Must be less than or equal to current version ${JSON.stringify(currentVersion)}.`,
388
525
  );
389
526
  }
390
527
 
391
- if (mode !== "test" && mode !== "update") {
528
+ if (mode !== "assert" && mode !== "update") {
392
529
  throw new UsageError(
393
- `Invalid mode: ${JSON.stringify(mode)}. Must be either "test" or "update".`,
530
+ `Invalid mode: ${JSON.stringify(mode)}. Must be either "assert" or "update".`,
394
531
  );
395
532
  }
396
533
 
397
534
  const currentEncodedForSnapshotting = exportCompatibilitySchemaSnapshot(currentViewSchema);
398
- const snapshots = checker.readAllSchemaSnapshots();
535
+ const snapshots = checker.readAllSchemaSnapshots(versionComparer);
399
536
 
400
537
  const compatibilityErrors: string[] = [];
401
538
 
402
- function updatableError(message: string): void {
403
- assert(mode === "test", 0xcc6 /* updatableError should only be called in test mode */);
404
- compatibilityErrors.push(
405
- `${message} If this is expected, checkSchemaCompatibilitySnapshots can be rerun in "update" mode to update the snapshot.`,
539
+ const contextNotes: string[] = [];
540
+
541
+ function errorWithContext(message: string): Error {
542
+ return new Error(
543
+ [
544
+ "Schema compatibility check failed:",
545
+ message,
546
+ `Snapshots in: ${JSON.stringify(options.snapshotDirectory)}`,
547
+ `Snapshots exist for versions: ${JSON.stringify([...snapshots.keys()], undefined, "\t")}.`,
548
+ ...contextNotes,
549
+ ].join("\n"),
406
550
  );
407
551
  }
408
552
 
409
- if (snapshotUnchangedVersions === true) {
410
- if (mode === "update") {
411
- checker.writeSchemaSnapshot(currentVersion, currentEncodedForSnapshotting);
412
- snapshots.set(currentVersion, currentViewSchema);
553
+ const compatibilityMap = transformMapValues(snapshots, (snapshot) =>
554
+ getCompatibility(currentViewSchema, snapshot),
555
+ );
556
+
557
+ // Either:
558
+ // - false: no update needed
559
+ // - the updateError message (update in update mode, error otherwise)
560
+ // - an error if the update is disallowed by the flags
561
+ let wouldUpdate: false | string | Error;
562
+
563
+ // Set wouldUpdate
564
+ {
565
+ const latestSnapshot = [...snapshots][snapshots.size - 1];
566
+ if (latestSnapshot === undefined) {
567
+ wouldUpdate = `No snapshots found.`;
413
568
  } else {
414
- const currentRead = snapshots.get(currentVersion);
415
- if (currentRead === undefined) {
416
- updatableError(
417
- `No snapshot found for version ${JSON.stringify(currentVersion)}: snapshotUnchangedVersions is true, so every version must be snapshotted.`,
569
+ const latestCompatibility =
570
+ compatibilityMap.get(latestSnapshot[0]) ??
571
+ fail(0xcd1 /* missing compatibilityMap entry */);
572
+
573
+ const schemaChange = !latestCompatibility.identicalCompatibility;
574
+ const versionChange = versionComparer(latestSnapshot[0], currentVersion) !== 0;
575
+
576
+ if (rejectVersionsWithNoSchemaChange === true && versionChange && !schemaChange) {
577
+ wouldUpdate = errorWithContext(
578
+ `Rejecting version change (${JSON.stringify(latestSnapshot[0])} to ${JSON.stringify(currentVersion)}) due to rejectVersionsWithNoSchemaChange being set.`,
418
579
  );
419
580
  } else if (
420
- JSON.stringify(exportCompatibilitySchemaSnapshot(currentRead)) !==
421
- JSON.stringify(currentEncodedForSnapshotting)
581
+ rejectSchemaChangesWithNoVersionChange === true &&
582
+ schemaChange &&
583
+ !versionChange
422
584
  ) {
423
- updatableError(
424
- `Snapshot for current version ${JSON.stringify(currentVersion)} is out of date.`,
585
+ wouldUpdate = errorWithContext(
586
+ `Rejecting schema change without version change due to existing non-equivalent snapshot for version (${JSON.stringify(latestSnapshot[0])} due to rejectSchemaChangesWithNoVersionChange being set.`,
425
587
  );
426
- }
427
- }
428
- } else {
429
- const entries = [...snapshots];
430
- const latestSnapshot = entries[entries.length - 1];
431
- if (latestSnapshot === undefined) {
432
- if (mode === "update") {
433
- checker.writeSchemaSnapshot(currentVersion, currentEncodedForSnapshotting);
434
- snapshots.set(currentVersion, currentViewSchema);
588
+ } else if (snapshotUnchangedVersions === true) {
589
+ const currentRead = snapshots.get(currentVersion);
590
+ if (currentRead === undefined) {
591
+ wouldUpdate = `No snapshot found for version ${JSON.stringify(currentVersion)}: snapshotUnchangedVersions is true, so every version must be snapshotted.`;
592
+ } else if (
593
+ JSON.stringify(exportCompatibilitySchemaSnapshot(currentRead)) ===
594
+ JSON.stringify(currentEncodedForSnapshotting)
595
+ ) {
596
+ wouldUpdate = false;
597
+ } else {
598
+ wouldUpdate = `Snapshot for current version ${JSON.stringify(currentVersion)} is out of date.`;
599
+ }
435
600
  } else {
436
- updatableError(`No snapshots found.`);
601
+ if (versionComparer(latestSnapshot[0], currentVersion) <= 0) {
602
+ wouldUpdate = schemaChange
603
+ ? `Snapshot for current version ${JSON.stringify(currentVersion)} is out of date: schema has changed since latest existing snapshot version ${JSON.stringify(latestSnapshot[0])}.`
604
+ : false;
605
+ } else {
606
+ wouldUpdate = errorWithContext(
607
+ `Current version ${JSON.stringify(currentVersion)} is less than latest existing snapshot version ${JSON.stringify(latestSnapshot[0])}: version is expected to increase monotonically.`,
608
+ );
609
+ }
437
610
  }
438
- } else {
439
- if (semver.lte(latestSnapshot[0], currentVersion)) {
440
- // Check to see if schema in snapshot is the same as the latest existing snapshot.
441
- const oldString = JSON.stringify(exportCompatibilitySchemaSnapshot(latestSnapshot[1]));
442
- const currentString = JSON.stringify(currentEncodedForSnapshotting);
443
- if (oldString !== currentString) {
444
- // Schema has changed: must create new snapshot.
445
- if (mode === "update") {
446
- checker.writeSchemaSnapshot(currentVersion, currentEncodedForSnapshotting);
447
- snapshots.set(currentVersion, currentViewSchema);
448
- } else {
449
- updatableError(
450
- `Snapshot for current version ${JSON.stringify(currentVersion)} is out of date: schema has changed since latest existing snapshot version ${JSON.stringify(latestSnapshot[0])}.`,
451
- );
452
- }
611
+
612
+ if (!schemaChange && (snapshotUnchangedVersions !== true || !versionChange)) {
613
+ // eslint-disable-next-line unicorn/no-lonely-if
614
+ if (
615
+ JSON.stringify(exportCompatibilitySchemaSnapshot(latestSnapshot[1])) !==
616
+ JSON.stringify(currentEncodedForSnapshotting)
617
+ ) {
618
+ // Schema are compatibility wise equivalent, but differ in some way (excluding json formatting).
619
+ // TODO: add a "normalize" mode, which do an update only in this case (or maybe even normalize json formatting as well and just always rewrite when !schemaChange)
620
+ // This would be useful to minimize diffs from future schema changes.
621
+ // This would be particularly useful if adding a second version of the format used in the snapshots.
453
622
  }
454
- } else {
455
- throw new UsageError(
456
- `Current version ${JSON.stringify(currentVersion)} is less than latest existing snapshot version ${JSON.stringify(latestSnapshot[0])}: version is expected to increase monotonically.`,
457
- );
458
623
  }
459
624
  }
460
625
  }
461
626
 
462
- const compatibilityMap = transformMapValues(snapshots, (snapshot) =>
463
- getCompatibility(currentViewSchema, snapshot),
464
- );
465
-
466
- let selectedMinVersionForCollaborationSnapshot:
467
- | undefined
468
- | readonly [string, CombinedSchemaCompatibilityStatus];
469
-
470
- if (snapshotUnchangedVersions === true) {
471
- const minSnapshot = compatibilityMap.get(minVersionForCollaboration);
472
- if (minSnapshot === undefined) {
473
- compatibilityErrors.push(
474
- `Using snapshotUnchangedVersions: a snapshot of the exact minVersionForCollaboration ${JSON.stringify(minVersionForCollaboration)} is required. No snapshot found.`,
627
+ if (wouldUpdate !== false) {
628
+ if (wouldUpdate instanceof Error) {
629
+ throw wouldUpdate;
630
+ }
631
+ if (mode === "update") {
632
+ checker.writeSchemaSnapshot(currentVersion, currentEncodedForSnapshotting);
633
+ // Update so errors below will reflect the new snapshot.
634
+ compatibilityMap.set(
635
+ currentVersion,
636
+ getCompatibility(currentViewSchema, currentViewSchema),
475
637
  );
476
638
  } else {
477
- selectedMinVersionForCollaborationSnapshot = [minVersionForCollaboration, minSnapshot];
478
- }
479
- } else {
480
- selectedMinVersionForCollaborationSnapshot = selectVersionRoundedDown(
481
- minVersionForCollaboration,
482
- compatibilityMap,
483
- );
484
- if (selectedMinVersionForCollaborationSnapshot === undefined) {
485
639
  compatibilityErrors.push(
486
- `No snapshot found with version less than or equal to minVersionForCollaboration ${JSON.stringify(minVersionForCollaboration)}.`,
640
+ `${wouldUpdate} If this is expected, snapshotSchemaCompatibility can be rerun in "update" mode to update or create the snapshot.`,
641
+ );
642
+
643
+ // This case could update compatibilityMap as well, but it would hide some information about how the existing snapshot might be incompatible with the proposed new one.
644
+ // This lost information could be annoying if the user's intention was not to edit the schema (which is what we assume in assert mode),
645
+ // especially once we produce more detailed error messages that can help users understand what changed in the schema.
646
+ }
647
+ }
648
+
649
+ // Add compatibilityErrors and contextNotes as needed regarding minVersionForCollaboration.
650
+ // This is only done when minVersionForCollaboration is not the current version to avoid extra noise in "assert" mode
651
+ // (which is the only case that could error when minVersionForCollaboration === currentVersion).
652
+ if (minVersionForCollaboration !== currentVersion) {
653
+ if (snapshotUnchangedVersions === true) {
654
+ const minSnapshot = compatibilityMap.get(minVersionForCollaboration);
655
+ if (minSnapshot === undefined) {
656
+ compatibilityErrors.push(
657
+ `Using snapshotUnchangedVersions: a snapshot of the exact minVersionForCollaboration ${JSON.stringify(minVersionForCollaboration)} is required. No snapshot found.`,
658
+ );
659
+ }
660
+ } else {
661
+ const selectedMinVersionForCollaborationSnapshot = selectVersionRoundedDown(
662
+ minVersionForCollaboration,
663
+ compatibilityMap,
664
+ versionComparer,
487
665
  );
666
+ if (selectedMinVersionForCollaborationSnapshot === undefined) {
667
+ compatibilityErrors.push(
668
+ `No snapshot found with version less than or equal to minVersionForCollaboration ${JSON.stringify(minVersionForCollaboration)}.`,
669
+ );
670
+ } else if (
671
+ selectedMinVersionForCollaborationSnapshot[0] !== minVersionForCollaboration
672
+ ) {
673
+ // Add an entry to ensure that the version which spans from before until after the cutoff for collaboration is included in the compatibility checks.
674
+ compatibilityMap.set(
675
+ minVersionForCollaboration,
676
+ selectedMinVersionForCollaborationSnapshot[1],
677
+ );
678
+ contextNotes.push(
679
+ `Due to snapshotUnchangedVersions being false and minVersionForCollaboration (${JSON.stringify(minVersionForCollaboration)}) not having an exact snapshot, the last snapshot before that version (which is ${JSON.stringify(
680
+ selectedMinVersionForCollaborationSnapshot[0],
681
+ )}) is being also being checked as if it is version ${JSON.stringify(minVersionForCollaboration)}.`,
682
+ );
683
+ }
488
684
  }
489
685
  }
490
686
 
687
+ // Compare all snapshots against the current schema, using the compatibilityMap.
491
688
  for (const [snapshotVersion, compatibility] of compatibilityMap) {
492
689
  // Current should be able to view all versions.
493
690
  if (!compatibility.currentViewOfSnapshotDocument.canUpgrade) {
@@ -496,56 +693,41 @@ export function checkSchemaCompatibilitySnapshots(
496
693
  );
497
694
  }
498
695
 
499
- if (semver.eq(snapshotVersion, currentVersion)) {
696
+ const versionComparisonToCurrent = versionComparer(snapshotVersion, currentVersion);
697
+ if (versionComparisonToCurrent === 0) {
500
698
  if (currentVersion !== snapshotVersion) {
501
- throw new UsageError(
699
+ throw errorWithContext(
502
700
  `Snapshot version ${JSON.stringify(snapshotVersion)} is semantically equal but not string equal to current version ${JSON.stringify(currentVersion)}: this is not supported.`,
503
701
  );
504
702
  }
505
- if (
506
- compatibility.currentViewOfSnapshotDocument.isEquivalent === false ||
507
- compatibility.snapshotViewOfCurrentDocument.isEquivalent === false
508
- ) {
509
- compatibilityErrors.push(
510
- `Current version ${JSON.stringify(snapshotVersion)} expected to be equivalent to its snapshot.`,
511
- );
512
- }
513
- } else if (semver.lt(snapshotVersion, currentVersion)) {
514
- if (selectedMinVersionForCollaborationSnapshot === undefined) {
703
+ if (compatibility.identicalCompatibility === false) {
515
704
  assert(
516
- compatibilityErrors.length > 0,
517
- 0xcc7 /* expected compatibility errors for missing min collab version snapshot */,
705
+ wouldUpdate !== false,
706
+ 0xcd2 /* there should have been an error for the snapshot being out of date */,
518
707
  );
519
- } else {
520
- // Collaboration with this version is expected to work.
521
- if (semver.gte(snapshotVersion, selectedMinVersionForCollaborationSnapshot[0])) {
522
- // Check that the historical version can view documents from the current version, since collaboration with this one is expected to work.
523
- if (!compatibility.snapshotViewOfCurrentDocument.canView) {
524
- const message = `Historical version ${JSON.stringify(snapshotVersion)} cannot view documents from ${JSON.stringify(currentVersion)}: these versions are expected to be able to collaborate due to the selected minVersionForCollaboration snapshot version being ${JSON.stringify(selectedMinVersionForCollaborationSnapshot[0])}.`;
525
- compatibilityErrors.push(
526
- selectedMinVersionForCollaborationSnapshot[0] === minVersionForCollaboration
527
- ? message
528
- : `${message} The specified minVersionForCollaboration is ${JSON.stringify(minVersionForCollaboration)} which was rounded down to an existing snapshot.`,
529
- );
530
- }
531
- } else {
532
- // This is the case where the historical version is less than the minimum version for collaboration.
533
- // No additional validation is needed here currently, since forwards document compat from these versions is already tested above (since it applies to all snapshots).
708
+ }
709
+ } else if (versionComparisonToCurrent < 0) {
710
+ // Collaboration with this version is expected to work.
711
+ if (versionComparer(snapshotVersion, minVersionForCollaboration) >= 0) {
712
+ // Check that the historical version can view documents from the current version, since collaboration with this one is expected to work.
713
+ if (!compatibility.snapshotViewOfCurrentDocument.canView) {
714
+ compatibilityErrors.push(
715
+ `Historical version ${JSON.stringify(snapshotVersion)} cannot view documents from ${JSON.stringify(currentVersion)}: these versions are expected to be able to collaborate due to the selected minVersionForCollaboration ${JSON.stringify(minVersionForCollaboration)}.`,
716
+ );
534
717
  }
718
+ } else {
719
+ // This is the case where the historical version is less than the minimum version for collaboration.
720
+ // No additional validation is needed here currently, since forwards document compat from these versions is already tested above (since it applies to all snapshots).
535
721
  }
536
722
  } else {
537
- throw new UsageError(
538
- `Unexpected semver comparison result between snapshot version ${JSON.stringify(snapshotVersion)} and app version ${JSON.stringify(currentVersion)}.`,
723
+ compatibilityErrors.push(
724
+ `Snapshot exists for version ${JSON.stringify(snapshotVersion)} which is greater than the current version ${JSON.stringify(currentVersion)}. This is not supported.`,
539
725
  );
540
726
  }
541
727
  }
542
728
 
543
729
  if (compatibilityErrors.length > 0) {
544
- throw new Error(
545
- `Schema compatibility check failed:\n${compatibilityErrors
546
- .map((e) => ` - ${e}`)
547
- .join("\n")}`,
548
- );
730
+ throw errorWithContext(compatibilityErrors.map((e) => ` - ${e}`).join("\n"));
549
731
  }
550
732
  }
551
733
 
@@ -570,7 +752,7 @@ export class SnapshotCompatibilityChecker {
570
752
  `${snapshotName}.json`,
571
753
  );
572
754
  this.ensureSnapshotDirectoryExists();
573
- this.fileSystemMethods.writeFileSync(fullPath, JSON.stringify(snapshot, undefined, 2), {
755
+ this.fileSystemMethods.writeFileSync(fullPath, JSON.stringify(snapshot, undefined, "\t"), {
574
756
  encoding: "utf8",
575
757
  });
576
758
  }
@@ -594,7 +776,9 @@ export class SnapshotCompatibilityChecker {
594
776
  /**
595
777
  * Returns all schema snapshots stored in the snapshot directory, sorted in order of increasing version.
596
778
  */
597
- public readAllSchemaSnapshots(): Map<string, TreeViewConfiguration> {
779
+ public readAllSchemaSnapshots(
780
+ compare: (a: string, b: string) => number,
781
+ ): Map<string, TreeViewConfiguration> {
598
782
  this.ensureSnapshotDirectoryExists();
599
783
  const files = this.fileSystemMethods.readdirSync(this.snapshotDirectory);
600
784
  const versions: string[] = [];
@@ -605,7 +789,7 @@ export class SnapshotCompatibilityChecker {
605
789
  }
606
790
  }
607
791
  // Ensures that errors are in a consistent and friendly order, independent of file system order.
608
- versions.sort((a, b) => semver.compare(a, b));
792
+ versions.sort(compare);
609
793
 
610
794
  const snapshots: Map<string, TreeViewConfiguration> = new Map();
611
795
  for (const version of versions) {
@@ -639,8 +823,26 @@ export function getCompatibility(
639
823
  previousViewSchema,
640
824
  );
641
825
 
826
+ assert(
827
+ backwardsCompatibilityStatus.isEquivalent === forwardsCompatibilityStatus.isEquivalent,
828
+ 0xcd3 /* equality should be symmetric */,
829
+ );
830
+
831
+ // This relies on exportCompatibilitySchemaSnapshot being well normalized, and not differing for non-significant changes.
832
+ const identicalCompatibility =
833
+ JSON.stringify(exportCompatibilitySchemaSnapshot(currentViewSchema)) ===
834
+ JSON.stringify(exportCompatibilitySchemaSnapshot(previousViewSchema));
835
+
836
+ if (identicalCompatibility) {
837
+ assert(
838
+ backwardsCompatibilityStatus.isEquivalent,
839
+ 0xcd4 /* identicalCompatibility should have equivalent stored schema */,
840
+ );
841
+ }
842
+
642
843
  return {
643
844
  currentViewOfSnapshotDocument: backwardsCompatibilityStatus,
644
845
  snapshotViewOfCurrentDocument: forwardsCompatibilityStatus,
846
+ identicalCompatibility,
645
847
  };
646
848
  }