@fluidframework/tree 2.0.0-dev-rc.5.0.0.271262 → 2.0.0-dev-rc.5.0.0.272251

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 (458) hide show
  1. package/api-extractor/api-extractor-lint-beta.cjs.json +5 -0
  2. package/api-extractor/api-extractor-lint-beta.esm.json +5 -0
  3. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  4. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  5. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  6. package/api-report/tree.alpha.api.md +2 -13
  7. package/api-report/tree.beta.api.md +2 -13
  8. package/api-report/tree.public.api.md +2 -13
  9. package/dist/beta.d.ts +0 -1
  10. package/dist/codec/codec.js +0 -1
  11. package/dist/codec/codec.js.map +1 -1
  12. package/dist/codec/discriminatedUnions.js +0 -1
  13. package/dist/codec/discriminatedUnions.js.map +1 -1
  14. package/dist/core/change-family/editBuilder.js +0 -2
  15. package/dist/core/change-family/editBuilder.js.map +1 -1
  16. package/dist/core/rebase/revisionTagCodec.js +0 -2
  17. package/dist/core/rebase/revisionTagCodec.js.map +1 -1
  18. package/dist/core/schema-stored/schema.js +0 -4
  19. package/dist/core/schema-stored/schema.js.map +1 -1
  20. package/dist/core/schema-stored/storedSchemaRepository.js +1 -3
  21. package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
  22. package/dist/core/schema-view/view.js +0 -2
  23. package/dist/core/schema-view/view.js.map +1 -1
  24. package/dist/core/tree/anchorSet.js +46 -51
  25. package/dist/core/tree/anchorSet.js.map +1 -1
  26. package/dist/core/tree/detachedFieldIndex.js +2 -8
  27. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  28. package/dist/core/tree/detachedFieldIndexCodec.js +0 -3
  29. package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
  30. package/dist/core/tree/sparseTree.js +11 -15
  31. package/dist/core/tree/sparseTree.js.map +1 -1
  32. package/dist/domains/schemaBuilder.js +70 -70
  33. package/dist/domains/schemaBuilder.js.map +1 -1
  34. package/dist/events/events.js +1 -2
  35. package/dist/events/events.js.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/basicChunk.js +1 -14
  37. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/chunkTree.js +6 -13
  39. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  40. package/dist/feature-libraries/chunked-forest/chunkedForest.js +2 -9
  41. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  42. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js +3 -1
  43. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -3
  45. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  46. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +6 -11
  47. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  48. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +3 -3
  49. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  50. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +2 -5
  51. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  52. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +0 -1
  53. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  54. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -1
  55. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  56. package/dist/feature-libraries/chunked-forest/codec/codecs.js +4 -1
  57. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  58. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +13 -25
  59. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  60. package/dist/feature-libraries/chunked-forest/codec/nodeShape.d.ts.map +1 -1
  61. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js +5 -8
  62. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  63. package/dist/feature-libraries/chunked-forest/sequenceChunk.js +0 -1
  64. package/dist/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
  65. package/dist/feature-libraries/chunked-forest/uniformChunk.js +5 -40
  66. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  67. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +0 -2
  68. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  69. package/dist/feature-libraries/detachedFieldIndexSummarizer.js +1 -2
  70. package/dist/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
  71. package/dist/feature-libraries/editableTreeBinder.js +12 -13
  72. package/dist/feature-libraries/editableTreeBinder.js.map +1 -1
  73. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +11 -12
  74. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  75. package/dist/feature-libraries/flex-tree/context.js +3 -7
  76. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  77. package/dist/feature-libraries/flex-tree/lazyEntity.js +22 -13
  78. package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  79. package/dist/feature-libraries/flex-tree/lazyField.js +0 -6
  80. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  81. package/dist/feature-libraries/flex-tree/lazyNode.js +17 -10
  82. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  83. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  84. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  85. package/dist/feature-libraries/index.d.ts +1 -1
  86. package/dist/feature-libraries/index.d.ts.map +1 -1
  87. package/dist/feature-libraries/index.js +2 -3
  88. package/dist/feature-libraries/index.js.map +1 -1
  89. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +7 -7
  90. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  91. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js +6 -6
  92. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  93. package/dist/feature-libraries/modular-schema/fieldKind.js +0 -2
  94. package/dist/feature-libraries/modular-schema/fieldKind.js.map +1 -1
  95. package/dist/feature-libraries/modular-schema/fieldKindWithEditor.js +0 -3
  96. package/dist/feature-libraries/modular-schema/fieldKindWithEditor.js.map +1 -1
  97. package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
  98. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  99. package/dist/feature-libraries/modular-schema/index.js +2 -2
  100. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  101. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +2 -0
  102. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  103. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +2 -0
  104. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  105. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +39 -24
  106. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  107. package/dist/feature-libraries/node-key/mockNodeKeyManager.js +4 -2
  108. package/dist/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  109. package/dist/feature-libraries/node-key/nodeKeyIndex.js +0 -3
  110. package/dist/feature-libraries/node-key/nodeKeyIndex.js.map +1 -1
  111. package/dist/feature-libraries/object-forest/objectForest.js +28 -23
  112. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  113. package/dist/feature-libraries/optional-field/optionalField.js +5 -3
  114. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  115. package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -5
  116. package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  117. package/dist/feature-libraries/schemaBuilderBase.js +3 -14
  118. package/dist/feature-libraries/schemaBuilderBase.js.map +1 -1
  119. package/dist/feature-libraries/sequence-field/compose.js +0 -6
  120. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  121. package/dist/feature-libraries/sequence-field/markListFactory.js +4 -3
  122. package/dist/feature-libraries/sequence-field/markListFactory.js.map +1 -1
  123. package/dist/feature-libraries/sequence-field/markQueue.js +2 -4
  124. package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
  125. package/dist/feature-libraries/sequence-field/rebase.d.ts +2 -2
  126. package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  127. package/dist/feature-libraries/sequence-field/rebase.js +20 -20
  128. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  129. package/dist/feature-libraries/treeCursorUtils.js +9 -13
  130. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  131. package/dist/feature-libraries/typed-schema/typedTreeSchema.js +4 -23
  132. package/dist/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  133. package/dist/feature-libraries/typed-schema/view.js +0 -7
  134. package/dist/feature-libraries/typed-schema/view.js.map +1 -1
  135. package/dist/index.d.ts +1 -1
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +1 -2
  138. package/dist/index.js.map +1 -1
  139. package/dist/packageVersion.d.ts +1 -1
  140. package/dist/packageVersion.js +1 -1
  141. package/dist/packageVersion.js.map +1 -1
  142. package/dist/public.d.ts +0 -1
  143. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  144. package/dist/shared-tree/schematizingTreeView.js +10 -27
  145. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  146. package/dist/shared-tree/sharedTree.d.ts +4 -0
  147. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  148. package/dist/shared-tree/sharedTree.js +13 -10
  149. package/dist/shared-tree/sharedTree.js.map +1 -1
  150. package/dist/shared-tree/sharedTreeChangeEnricher.js +11 -14
  151. package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  152. package/dist/shared-tree/sharedTreeChangeFamily.js +3 -5
  153. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  154. package/dist/shared-tree/sharedTreeEditBuilder.js +0 -2
  155. package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  156. package/dist/shared-tree/treeCheckout.js +11 -22
  157. package/dist/shared-tree/treeCheckout.js.map +1 -1
  158. package/dist/shared-tree/treeView.js +0 -6
  159. package/dist/shared-tree/treeView.js.map +1 -1
  160. package/dist/shared-tree-core/branch.d.ts +18 -0
  161. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  162. package/dist/shared-tree-core/branch.js +28 -31
  163. package/dist/shared-tree-core/branch.js.map +1 -1
  164. package/dist/shared-tree-core/branchCommitEnricher.d.ts +4 -2
  165. package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  166. package/dist/shared-tree-core/branchCommitEnricher.js +19 -15
  167. package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
  168. package/dist/shared-tree-core/defaultResubmitMachine.js +19 -21
  169. package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  170. package/dist/shared-tree-core/editManager.js +37 -53
  171. package/dist/shared-tree-core/editManager.js.map +1 -1
  172. package/dist/shared-tree-core/editManagerSummarizer.js +1 -5
  173. package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
  174. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  175. package/dist/shared-tree-core/sharedTreeCore.js +16 -24
  176. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  177. package/dist/shared-tree-core/transactionEnricher.d.ts +11 -1
  178. package/dist/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  179. package/dist/shared-tree-core/transactionEnricher.js +25 -4
  180. package/dist/shared-tree-core/transactionEnricher.js.map +1 -1
  181. package/dist/shared-tree-core/transactionStack.js +3 -1
  182. package/dist/shared-tree-core/transactionStack.js.map +1 -1
  183. package/dist/simple-tree/arrayNode.js +34 -26
  184. package/dist/simple-tree/arrayNode.js.map +1 -1
  185. package/dist/simple-tree/leafNodeSchema.js +2 -4
  186. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  187. package/dist/simple-tree/mapNode.js +5 -5
  188. package/dist/simple-tree/mapNode.js.map +1 -1
  189. package/dist/simple-tree/objectNode.js +6 -6
  190. package/dist/simple-tree/objectNode.js.map +1 -1
  191. package/dist/simple-tree/schemaFactory.d.ts +18 -5
  192. package/dist/simple-tree/schemaFactory.d.ts.map +1 -1
  193. package/dist/simple-tree/schemaFactory.js +65 -53
  194. package/dist/simple-tree/schemaFactory.js.map +1 -1
  195. package/dist/simple-tree/schemaTypes.js +3 -12
  196. package/dist/simple-tree/schemaTypes.js.map +1 -1
  197. package/dist/simple-tree/tree.d.ts +1 -22
  198. package/dist/simple-tree/tree.d.ts.map +1 -1
  199. package/dist/simple-tree/tree.js +0 -21
  200. package/dist/simple-tree/tree.js.map +1 -1
  201. package/dist/simple-tree/treeNodeApi.d.ts +13 -4
  202. package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
  203. package/dist/simple-tree/treeNodeApi.js +8 -3
  204. package/dist/simple-tree/treeNodeApi.js.map +1 -1
  205. package/dist/simple-tree/types.d.ts +26 -6
  206. package/dist/simple-tree/types.d.ts.map +1 -1
  207. package/dist/simple-tree/types.js +79 -54
  208. package/dist/simple-tree/types.js.map +1 -1
  209. package/dist/treeFactory.js +10 -9
  210. package/dist/treeFactory.js.map +1 -1
  211. package/dist/util/brand.js +0 -1
  212. package/dist/util/brand.js.map +1 -1
  213. package/dist/util/nestedMap.js +4 -2
  214. package/dist/util/nestedMap.js.map +1 -1
  215. package/dist/util/offsetList.js +4 -2
  216. package/dist/util/offsetList.js.map +1 -1
  217. package/dist/util/referenceCounting.js +0 -1
  218. package/dist/util/referenceCounting.js.map +1 -1
  219. package/dist/util/stackyIterator.js +2 -3
  220. package/dist/util/stackyIterator.js.map +1 -1
  221. package/lib/beta.d.ts +0 -1
  222. package/lib/codec/codec.js +0 -1
  223. package/lib/codec/codec.js.map +1 -1
  224. package/lib/codec/discriminatedUnions.js +0 -1
  225. package/lib/codec/discriminatedUnions.js.map +1 -1
  226. package/lib/core/change-family/editBuilder.js +0 -2
  227. package/lib/core/change-family/editBuilder.js.map +1 -1
  228. package/lib/core/rebase/revisionTagCodec.js +0 -2
  229. package/lib/core/rebase/revisionTagCodec.js.map +1 -1
  230. package/lib/core/schema-stored/schema.js +0 -4
  231. package/lib/core/schema-stored/schema.js.map +1 -1
  232. package/lib/core/schema-stored/storedSchemaRepository.js +1 -3
  233. package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
  234. package/lib/core/schema-view/view.js +0 -2
  235. package/lib/core/schema-view/view.js.map +1 -1
  236. package/lib/core/tree/anchorSet.js +46 -51
  237. package/lib/core/tree/anchorSet.js.map +1 -1
  238. package/lib/core/tree/detachedFieldIndex.js +2 -8
  239. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  240. package/lib/core/tree/detachedFieldIndexCodec.js +0 -3
  241. package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
  242. package/lib/core/tree/sparseTree.js +11 -15
  243. package/lib/core/tree/sparseTree.js.map +1 -1
  244. package/lib/domains/schemaBuilder.js +70 -70
  245. package/lib/domains/schemaBuilder.js.map +1 -1
  246. package/lib/events/events.js +1 -2
  247. package/lib/events/events.js.map +1 -1
  248. package/lib/feature-libraries/chunked-forest/basicChunk.js +1 -14
  249. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  250. package/lib/feature-libraries/chunked-forest/chunkTree.js +6 -13
  251. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  252. package/lib/feature-libraries/chunked-forest/chunkedForest.js +2 -9
  253. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  254. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js +3 -1
  255. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
  256. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -3
  257. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  258. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +6 -11
  259. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  260. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +3 -3
  261. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  262. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +2 -5
  263. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  264. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +0 -1
  265. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  266. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -1
  267. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  268. package/lib/feature-libraries/chunked-forest/codec/codecs.js +4 -1
  269. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  270. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +13 -25
  271. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  272. package/lib/feature-libraries/chunked-forest/codec/nodeShape.d.ts.map +1 -1
  273. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js +5 -8
  274. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  275. package/lib/feature-libraries/chunked-forest/sequenceChunk.js +0 -1
  276. package/lib/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
  277. package/lib/feature-libraries/chunked-forest/uniformChunk.js +5 -40
  278. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  279. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +0 -2
  280. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  281. package/lib/feature-libraries/detachedFieldIndexSummarizer.js +1 -2
  282. package/lib/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
  283. package/lib/feature-libraries/editableTreeBinder.js +12 -13
  284. package/lib/feature-libraries/editableTreeBinder.js.map +1 -1
  285. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +11 -12
  286. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  287. package/lib/feature-libraries/flex-tree/context.js +3 -7
  288. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  289. package/lib/feature-libraries/flex-tree/lazyEntity.js +22 -13
  290. package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  291. package/lib/feature-libraries/flex-tree/lazyField.js +0 -6
  292. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  293. package/lib/feature-libraries/flex-tree/lazyNode.js +17 -10
  294. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  295. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  296. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  297. package/lib/feature-libraries/index.d.ts +1 -1
  298. package/lib/feature-libraries/index.d.ts.map +1 -1
  299. package/lib/feature-libraries/index.js +1 -1
  300. package/lib/feature-libraries/index.js.map +1 -1
  301. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +7 -7
  302. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  303. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js +5 -5
  304. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  305. package/lib/feature-libraries/modular-schema/fieldKind.js +0 -2
  306. package/lib/feature-libraries/modular-schema/fieldKind.js.map +1 -1
  307. package/lib/feature-libraries/modular-schema/fieldKindWithEditor.js +0 -3
  308. package/lib/feature-libraries/modular-schema/fieldKindWithEditor.js.map +1 -1
  309. package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
  310. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  311. package/lib/feature-libraries/modular-schema/index.js +1 -1
  312. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  313. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +2 -0
  314. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  315. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +2 -0
  316. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  317. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +40 -25
  318. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  319. package/lib/feature-libraries/node-key/mockNodeKeyManager.js +4 -2
  320. package/lib/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  321. package/lib/feature-libraries/node-key/nodeKeyIndex.js +0 -3
  322. package/lib/feature-libraries/node-key/nodeKeyIndex.js.map +1 -1
  323. package/lib/feature-libraries/object-forest/objectForest.js +28 -23
  324. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  325. package/lib/feature-libraries/optional-field/optionalField.js +6 -4
  326. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  327. package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -5
  328. package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  329. package/lib/feature-libraries/schemaBuilderBase.js +3 -14
  330. package/lib/feature-libraries/schemaBuilderBase.js.map +1 -1
  331. package/lib/feature-libraries/sequence-field/compose.js +0 -6
  332. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  333. package/lib/feature-libraries/sequence-field/markListFactory.js +4 -3
  334. package/lib/feature-libraries/sequence-field/markListFactory.js.map +1 -1
  335. package/lib/feature-libraries/sequence-field/markQueue.js +2 -4
  336. package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
  337. package/lib/feature-libraries/sequence-field/rebase.d.ts +2 -2
  338. package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  339. package/lib/feature-libraries/sequence-field/rebase.js +21 -21
  340. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  341. package/lib/feature-libraries/treeCursorUtils.js +9 -13
  342. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  343. package/lib/feature-libraries/typed-schema/typedTreeSchema.js +4 -23
  344. package/lib/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  345. package/lib/feature-libraries/typed-schema/view.js +0 -7
  346. package/lib/feature-libraries/typed-schema/view.js.map +1 -1
  347. package/lib/index.d.ts +1 -1
  348. package/lib/index.d.ts.map +1 -1
  349. package/lib/index.js +1 -1
  350. package/lib/index.js.map +1 -1
  351. package/lib/packageVersion.d.ts +1 -1
  352. package/lib/packageVersion.js +1 -1
  353. package/lib/packageVersion.js.map +1 -1
  354. package/lib/public.d.ts +0 -1
  355. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  356. package/lib/shared-tree/schematizingTreeView.js +10 -27
  357. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  358. package/lib/shared-tree/sharedTree.d.ts +4 -0
  359. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  360. package/lib/shared-tree/sharedTree.js +13 -10
  361. package/lib/shared-tree/sharedTree.js.map +1 -1
  362. package/lib/shared-tree/sharedTreeChangeEnricher.js +11 -14
  363. package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  364. package/lib/shared-tree/sharedTreeChangeFamily.js +3 -5
  365. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  366. package/lib/shared-tree/sharedTreeEditBuilder.js +0 -2
  367. package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  368. package/lib/shared-tree/treeCheckout.js +11 -22
  369. package/lib/shared-tree/treeCheckout.js.map +1 -1
  370. package/lib/shared-tree/treeView.js +0 -6
  371. package/lib/shared-tree/treeView.js.map +1 -1
  372. package/lib/shared-tree-core/branch.d.ts +18 -0
  373. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  374. package/lib/shared-tree-core/branch.js +28 -31
  375. package/lib/shared-tree-core/branch.js.map +1 -1
  376. package/lib/shared-tree-core/branchCommitEnricher.d.ts +4 -2
  377. package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  378. package/lib/shared-tree-core/branchCommitEnricher.js +19 -15
  379. package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
  380. package/lib/shared-tree-core/defaultResubmitMachine.js +19 -21
  381. package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  382. package/lib/shared-tree-core/editManager.js +37 -53
  383. package/lib/shared-tree-core/editManager.js.map +1 -1
  384. package/lib/shared-tree-core/editManagerSummarizer.js +1 -5
  385. package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
  386. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  387. package/lib/shared-tree-core/sharedTreeCore.js +16 -24
  388. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  389. package/lib/shared-tree-core/transactionEnricher.d.ts +11 -1
  390. package/lib/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  391. package/lib/shared-tree-core/transactionEnricher.js +25 -4
  392. package/lib/shared-tree-core/transactionEnricher.js.map +1 -1
  393. package/lib/shared-tree-core/transactionStack.js +3 -1
  394. package/lib/shared-tree-core/transactionStack.js.map +1 -1
  395. package/lib/simple-tree/arrayNode.js +34 -26
  396. package/lib/simple-tree/arrayNode.js.map +1 -1
  397. package/lib/simple-tree/leafNodeSchema.js +2 -4
  398. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  399. package/lib/simple-tree/mapNode.js +5 -5
  400. package/lib/simple-tree/mapNode.js.map +1 -1
  401. package/lib/simple-tree/objectNode.js +6 -6
  402. package/lib/simple-tree/objectNode.js.map +1 -1
  403. package/lib/simple-tree/schemaFactory.d.ts +18 -5
  404. package/lib/simple-tree/schemaFactory.d.ts.map +1 -1
  405. package/lib/simple-tree/schemaFactory.js +65 -53
  406. package/lib/simple-tree/schemaFactory.js.map +1 -1
  407. package/lib/simple-tree/schemaTypes.js +3 -12
  408. package/lib/simple-tree/schemaTypes.js.map +1 -1
  409. package/lib/simple-tree/tree.d.ts +1 -22
  410. package/lib/simple-tree/tree.d.ts.map +1 -1
  411. package/lib/simple-tree/tree.js +0 -21
  412. package/lib/simple-tree/tree.js.map +1 -1
  413. package/lib/simple-tree/treeNodeApi.d.ts +13 -4
  414. package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
  415. package/lib/simple-tree/treeNodeApi.js +8 -3
  416. package/lib/simple-tree/treeNodeApi.js.map +1 -1
  417. package/lib/simple-tree/types.d.ts +26 -6
  418. package/lib/simple-tree/types.d.ts.map +1 -1
  419. package/lib/simple-tree/types.js +78 -54
  420. package/lib/simple-tree/types.js.map +1 -1
  421. package/lib/treeFactory.js +10 -9
  422. package/lib/treeFactory.js.map +1 -1
  423. package/lib/util/brand.js +0 -1
  424. package/lib/util/brand.js.map +1 -1
  425. package/lib/util/nestedMap.js +4 -2
  426. package/lib/util/nestedMap.js.map +1 -1
  427. package/lib/util/offsetList.js +4 -2
  428. package/lib/util/offsetList.js.map +1 -1
  429. package/lib/util/referenceCounting.js +0 -1
  430. package/lib/util/referenceCounting.js.map +1 -1
  431. package/lib/util/stackyIterator.js +2 -3
  432. package/lib/util/stackyIterator.js.map +1 -1
  433. package/package.json +27 -24
  434. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +22 -6
  435. package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +2 -2
  436. package/src/feature-libraries/chunked-forest/codec/codecs.ts +6 -2
  437. package/src/feature-libraries/chunked-forest/codec/nodeShape.ts +8 -3
  438. package/src/feature-libraries/index.ts +0 -1
  439. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +6 -7
  440. package/src/feature-libraries/modular-schema/index.ts +1 -1
  441. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +2 -0
  442. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +55 -23
  443. package/src/feature-libraries/optional-field/optionalField.ts +3 -3
  444. package/src/feature-libraries/sequence-field/rebase.ts +15 -33
  445. package/src/index.ts +0 -1
  446. package/src/packageVersion.ts +1 -1
  447. package/src/shared-tree/schematizingTreeView.ts +0 -2
  448. package/src/shared-tree/sharedTree.ts +8 -1
  449. package/src/shared-tree-core/branch.ts +24 -0
  450. package/src/shared-tree-core/branchCommitEnricher.ts +15 -6
  451. package/src/shared-tree-core/sharedTreeCore.ts +9 -0
  452. package/src/shared-tree-core/transactionEnricher.ts +27 -1
  453. package/src/simple-tree/arrayNode.ts +17 -17
  454. package/src/simple-tree/schemaFactory.ts +18 -5
  455. package/src/simple-tree/tree.ts +1 -26
  456. package/src/simple-tree/treeNodeApi.ts +25 -7
  457. package/src/simple-tree/types.ts +57 -9
  458. package/tsdoc.json +4 -0
@@ -120,6 +120,27 @@ export interface SharedTreeBranchEvents<TEditor extends ChangeFamilyEditor, TCha
120
120
  * Fired after this branch is disposed
121
121
  */
122
122
  dispose(): void;
123
+
124
+ /**
125
+ * Fired after a new transaction is started.
126
+ * @param isOuterTransaction - true iff the transaction being started is the outermost transaction
127
+ * as opposed to a nested transaction.
128
+ */
129
+ transactionStarted(isOuterTransaction: boolean): void;
130
+
131
+ /**
132
+ * Fired after the current transaction is aborted.
133
+ * @param isOuterTransaction - true iff the transaction being aborted is the outermost transaction
134
+ * as opposed to a nested transaction.
135
+ */
136
+ transactionAborted(isOuterTransaction: boolean): void;
137
+
138
+ /**
139
+ * Fired after the current transaction is committed.
140
+ * @param isOuterTransaction - true iff the transaction being committed is the outermost transaction
141
+ * as opposed to a nested transaction.
142
+ */
143
+ transactionCommitted(isOuterTransaction: boolean): void;
123
144
  }
124
145
 
125
146
  /**
@@ -267,6 +288,7 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> exten
267
288
  onForkUnSubscribe();
268
289
  });
269
290
  this.editor.enterTransaction();
291
+ this.emit("transactionStarted", this.transactions.size === 1);
270
292
  }
271
293
 
272
294
  /**
@@ -283,6 +305,7 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> exten
283
305
  const [startCommit, commits] = this.popTransaction();
284
306
  this.editor.exitTransaction();
285
307
 
308
+ this.emit("transactionCommitted", this.transactions.size === 0);
286
309
  if (commits.length === 0) {
287
310
  return undefined;
288
311
  }
@@ -329,6 +352,7 @@ export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> exten
329
352
  const [startCommit, commits] = this.popTransaction();
330
353
  this.editor.exitTransaction();
331
354
 
355
+ this.emit("transactionAborted", this.transactions.size === 0);
332
356
  if (commits.length === 0) {
333
357
  return [undefined, []];
334
358
  }
@@ -12,8 +12,7 @@ import { TransactionEnricher } from "./transactionEnricher.js";
12
12
  * Utility for enriching commits from a {@link Branch} before these commits are applied and submitted.
13
13
  */
14
14
  export class BranchCommitEnricher<TChange> {
15
- private transactionEnricher?: TransactionEnricher<TChange>;
16
- private readonly rebaser: ChangeRebaser<TChange>;
15
+ private readonly transactionEnricher: TransactionEnricher<TChange>;
17
16
  private readonly enricher: ChangeEnricherReadonlyCheckout<TChange>;
18
17
  /**
19
18
  * Maps each local commit to the corresponding enriched commit.
@@ -28,8 +27,8 @@ export class BranchCommitEnricher<TChange> {
28
27
  rebaser: ChangeRebaser<TChange>,
29
28
  enricher: ChangeEnricherReadonlyCheckout<TChange>,
30
29
  ) {
31
- this.rebaser = rebaser;
32
30
  this.enricher = enricher;
31
+ this.transactionEnricher = new TransactionEnricher(rebaser, this.enricher);
33
32
  }
34
33
 
35
34
  /**
@@ -39,6 +38,18 @@ export class BranchCommitEnricher<TChange> {
39
38
  return this.preparedCommits.size;
40
39
  }
41
40
 
41
+ public startNewTransaction(): void {
42
+ this.transactionEnricher.startNewTransaction();
43
+ }
44
+
45
+ public commitCurrentTransaction(): void {
46
+ this.transactionEnricher.commitCurrentTransaction();
47
+ }
48
+
49
+ public abortCurrentTransaction(): void {
50
+ this.transactionEnricher.abortCurrentTransaction();
51
+ }
52
+
42
53
  /**
43
54
  * Adds a commit to the enricher.
44
55
  * @param commit - A commit that is part of a transaction.
@@ -46,8 +57,7 @@ export class BranchCommitEnricher<TChange> {
46
57
  public ingestTransactionCommit(commit: GraphCommit<TChange>): void {
47
58
  // We do not submit ops for changes that are part of a transaction.
48
59
  // But we need to enrich the commits that will be sent if the transaction is committed.
49
- this.transactionEnricher ??= new TransactionEnricher(this.rebaser, this.enricher);
50
- this.transactionEnricher.addTransactionSteps(commit);
60
+ this.transactionEnricher.addTransactionStep(commit);
51
61
  }
52
62
 
53
63
  /**
@@ -66,7 +76,6 @@ export class BranchCommitEnricher<TChange> {
66
76
  "Unexpected transaction commit without transaction steps",
67
77
  );
68
78
  enrichedChange = this.transactionEnricher.getComposedChange(commit.revision);
69
- delete this.transactionEnricher;
70
79
  } else {
71
80
  enrichedChange = this.enricher.updateChangeEnrichments(commit.change, commit.revision);
72
81
  }
@@ -151,6 +151,15 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends
151
151
  */
152
152
  const localSessionId = runtime.idCompressor.localSessionId;
153
153
  this.editManager = new EditManager(changeFamily, localSessionId, this.mintRevisionTag);
154
+ this.editManager.localBranch.on("transactionStarted", () => {
155
+ this.commitEnricher.startNewTransaction();
156
+ });
157
+ this.editManager.localBranch.on("transactionAborted", () => {
158
+ this.commitEnricher.abortCurrentTransaction();
159
+ });
160
+ this.editManager.localBranch.on("transactionCommitted", () => {
161
+ this.commitEnricher.commitCurrentTransaction();
162
+ });
154
163
  this.editManager.localBranch.on("beforeChange", (change) => {
155
164
  // Ensure that any previously prepared commits that have not been sent are purged.
156
165
  this.commitEnricher.purgePreparedCommits();
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { assert } from "@fluidframework/core-utils/internal";
6
7
  import type { ChangeRebaser, GraphCommit, RevisionTag } from "../core/index.js";
7
8
  import type { ChangeEnricherReadonlyCheckout } from "./changeEnricher.js";
8
9
 
@@ -13,6 +14,13 @@ export class TransactionEnricher<TChange> {
13
14
  private readonly rebaser: ChangeRebaser<TChange>;
14
15
  private readonly enricher: ChangeEnricherReadonlyCheckout<TChange>;
15
16
  private readonly transactionCommits: GraphCommit<TChange>[] = [];
17
+ /**
18
+ * The number of commits before the start of each active transaction scope.
19
+ * For a stack of `n` transaction scopes, the array will contain `n` integers,
20
+ * where the integer at index `i` is the number of commits made before the start of the `i`th transaction scope
21
+ * (therefore, the first element in the array, if present, is always 0)
22
+ */
23
+ private readonly transactionScopesStart: number[] = [];
16
24
 
17
25
  public constructor(
18
26
  rebaser: ChangeRebaser<TChange>,
@@ -22,14 +30,32 @@ export class TransactionEnricher<TChange> {
22
30
  this.enricher = enricher;
23
31
  }
24
32
 
25
- public addTransactionSteps(commit: GraphCommit<TChange>): void {
33
+ public startNewTransaction(): void {
34
+ this.transactionScopesStart.push(this.transactionCommits.length);
35
+ }
36
+
37
+ public commitCurrentTransaction(): void {
38
+ const commitsCommitted = this.transactionScopesStart.pop();
39
+ assert(commitsCommitted !== undefined, "No transaction to commit");
40
+ }
41
+
42
+ public abortCurrentTransaction(): void {
43
+ const scopeStart = this.transactionScopesStart.pop();
44
+ assert(scopeStart !== undefined, "No transaction to abort");
45
+ this.transactionCommits.length = scopeStart;
46
+ }
47
+
48
+ public addTransactionStep(commit: GraphCommit<TChange>): void {
49
+ assert(this.transactionScopesStart.length !== 0, "No transaction to add a step to");
26
50
  const change = this.enricher.updateChangeEnrichments(commit.change, commit.revision);
27
51
  this.transactionCommits.push({ ...commit, change });
28
52
  }
29
53
 
30
54
  public getComposedChange(revision: RevisionTag): TChange {
55
+ assert(this.transactionScopesStart.length === 0, "Transaction not committed");
31
56
  const squashed = this.rebaser.compose(this.transactionCommits);
32
57
  const tagged = this.rebaser.changeRevision(squashed, revision);
58
+ this.transactionCommits.length = 0;
33
59
  return tagged;
34
60
  }
35
61
  }
@@ -376,34 +376,34 @@ declare abstract class NodeWithArrayFeatures<Input, T>
376
376
  {
377
377
  concat(...items: ConcatArray<T>[]): T[];
378
378
  concat(...items: (T | ConcatArray<T>)[]): T[];
379
- join(separator?: string | undefined): string;
380
- slice(start?: number | undefined, end?: number | undefined): T[];
381
- indexOf(searchElement: T, fromIndex?: number | undefined): number;
382
- lastIndexOf(searchElement: T, fromIndex?: number | undefined): number;
379
+ entries(): IterableIterator<[number, T]>;
383
380
  every<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): this is readonly S[];
384
381
  every(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;
385
- some(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;
386
- forEach(callbackfn: (value: T, index: number, array: readonly T[]) => void, thisArg?: any): void;
387
- map<U>(callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any): U[];
388
382
  filter<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): S[];
389
383
  filter(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): T[];
384
+ find<S extends T>(predicate: (value: T, index: number, obj: readonly T[]) => value is S, thisArg?: any): S | undefined;
385
+ find(predicate: (value: T, index: number, obj: readonly T[]) => unknown, thisArg?: any): T | undefined;
386
+ findIndex(predicate: (value: T, index: number, obj: readonly T[]) => unknown, thisArg?: any): number;
387
+ flat<A, D extends number = 1>(this: A, depth?: D | undefined): FlatArray<A, D>[];
388
+ flatMap<U, This = undefined>(callback: (this: This, value: T, index: number, array: T[]) => U | readonly U[], thisArg?: This | undefined): U[];
389
+ forEach(callbackfn: (value: T, index: number, array: readonly T[]) => void, thisArg?: any): void;
390
+ includes(searchElement: T, fromIndex?: number | undefined): boolean;
391
+ indexOf(searchElement: T, fromIndex?: number | undefined): number;
392
+ join(separator?: string | undefined): string;
393
+ keys(): IterableIterator<number>;
394
+ lastIndexOf(searchElement: T, fromIndex?: number | undefined): number;
395
+ map<U>(callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any): U[];
390
396
  reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T;
391
397
  reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T, initialValue: T): T;
392
398
  reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U, initialValue: U): U;
393
399
  reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T;
394
400
  reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T, initialValue: T): T;
395
401
  reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U, initialValue: U): U;
396
- find<S extends T>(predicate: (value: T, index: number, obj: readonly T[]) => value is S, thisArg?: any): S | undefined;
397
- find(predicate: (value: T, index: number, obj: readonly T[]) => unknown, thisArg?: any): T | undefined;
398
- findIndex(predicate: (value: T, index: number, obj: readonly T[]) => unknown, thisArg?: any): number;
399
- entries(): IterableIterator<[number, T]>;
400
- keys(): IterableIterator<number>;
401
- values(): IterableIterator<T>;
402
- includes(searchElement: T, fromIndex?: number | undefined): boolean;
403
- flatMap<U, This = undefined>(callback: (this: This, value: T, index: number, array: T[]) => U | readonly U[], thisArg?: This | undefined): U[];
404
- flat<A, D extends number = 1>(this: A, depth?: D | undefined): FlatArray<A, D>[];
405
- toString(): string;
402
+ slice(start?: number | undefined, end?: number | undefined): T[];
403
+ some(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;
406
404
  toLocaleString(): string;
405
+ toString(): string;
406
+ values(): IterableIterator<T>;
407
407
  }
408
408
  /* eslint-enable @typescript-eslint/explicit-member-accessibility, @typescript-eslint/no-explicit-any */
409
409
 
@@ -567,11 +567,24 @@ export class SchemaFactory<
567
567
  }
568
568
 
569
569
  /**
570
- * Make a field of type identifier instead of the default, which is required.
571
- * @remarks Identifiers may be optionally supplied at node construction time.
572
- * If not supplied, they will be generated automatically when the node is inserted into the tree.
573
- * Attempting to read an automatically generated identifier before the node is inserted into the tree will throw an error.
574
- * An automatically generated identifier will not be present when iterating the nodes's fields until after the node is inserted into the tree.
570
+ * A special field which holds a unique identifier for an object node.
571
+ * @remarks
572
+ * The value of this field, a "node identifier", uniquely identifies a node among all other nodes in the tree.
573
+ * Node identifiers are strings, and can therefore be used as lookup keys in maps or written to a database.
574
+ * When the node is constructed, the identifier field does not need to be populated.
575
+ * The SharedTree will provide an identifier for the node automatically.
576
+ * An identifier provided automatically by the SharedTree has the following properties:
577
+ * - It is a UUID.
578
+ * - It is compressed to a space-efficient representation when stored in the document.
579
+ * - A compressed form of the identifier can be accessed at runtime via the `Tree.shortId()` API.
580
+ * - It will error if read (and will not be present in the object's iterable properties) before the node has been inserted into the tree.
581
+ *
582
+ * However, a user may alternatively supply their own string as the identifier if desired (for example, if importing identifiers from another system).
583
+ * In that case, it is up to the user to ensure that the identifier is unique within the current tree - no other node should have the same identifier at the same time.
584
+ * If the identifier is not unique, it may be read, but may cause libraries or features which operate over node identifiers to misbehave.
585
+ * User-supplied identifiers may be read immediately, even before insertion into the tree.
586
+ *
587
+ * A node may have more than one identifier field (though note that this precludes the use of the `Tree.shortId()` API).
575
588
  */
576
589
  public get identifier(): FieldSchema<FieldKind.Identifier, typeof this.string> {
577
590
  const defaultIdentifierProvider: DefaultProvider = getDefaultProvider(
@@ -57,30 +57,10 @@ export interface ITree extends IFluidLoadable {
57
57
  viewWith<TRoot extends ImplicitFieldSchema>(
58
58
  config: TreeViewConfiguration<TRoot>,
59
59
  ): TreeView<TRoot>;
60
-
61
- /**
62
- * Returns a {@link TreeView} using the provided schema.
63
- * If the stored schema is view-compatible with the view schema specified by `config`,
64
- * the returned {@link TreeView} will expose the root with a schema-aware API based on the provided view schema.
65
- * See {@link TreeView.compatibility} for information about the compatibility between the view and stored schemas.
66
- *
67
- * @remarks
68
- * If the tree is uninitialized, it will be implicitly initialized by this function.
69
- *
70
- * Note that other clients can modify the document at any time, causing the view to change its compatibility status: see {@link TreeView.events} for how to handle invalidation in these cases.
71
- *
72
- * Only one schematized view may exist for a given ITree at a time.
73
- * If creating a second, the first must be disposed before calling `schematize` again.
74
- * @deprecated Replaced by {@link ITree.viewWith}. Use that method instead. Note that `viewWith` does not implicitly initialize the tree:
75
- * to initialize it, call {@link TreeView.initialize} on the returned view.
76
- */
77
- schematize<TRoot extends ImplicitFieldSchema>(
78
- config: TreeConfiguration<TRoot>,
79
- ): TreeView<TRoot>;
80
60
  }
81
61
 
82
62
  /**
83
- * Options when schematizing a tree.
63
+ * Options when constructing a tree view.
84
64
  * @public
85
65
  */
86
66
  export interface ITreeConfigurationOptions {
@@ -342,11 +322,6 @@ export interface SchemaCompatibilityStatus {
342
322
  * @public
343
323
  */
344
324
  export interface TreeViewEvents {
345
- /**
346
- * A batch of changes has finished processing and the view has been updated.
347
- */
348
- afterBatch(): void;
349
-
350
325
  /**
351
326
  * Raised whenever {@link TreeView.root} is invalidated.
352
327
  *
@@ -36,6 +36,7 @@ import {
36
36
  stringSchema,
37
37
  } from "./leafNodeSchema.js";
38
38
  import { isFluidHandle } from "@fluidframework/runtime-utils/internal";
39
+ import { UsageError } from "@fluidframework/telemetry-utils/internal";
39
40
 
40
41
  /**
41
42
  * Provides various functions for analyzing {@link TreeNode}s.
@@ -101,11 +102,20 @@ export interface TreeNodeApi {
101
102
  readonly status: (node: TreeNode) => TreeStatus;
102
103
 
103
104
  /**
104
- * Returns the {@link FieldKind.Identifier | identifier} of the given node in the most compressed form possible.
105
+ * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.
105
106
  * @remarks
106
- * If the node's identifier is a valid `StableNodeKey`, then this will return a unique process-local integer corresponding to that identifier.
107
- * If the node's identifier is any other string, then this will return that string.
108
- * If the node has no identifier (that is, it has no field of an {@link FieldKind.Identifier | identifier} field kind), then this returns undefined.
107
+ * If the node's identifier is a valid UUID that was automatically generated by the SharedTree, then this will return a process-unique integer corresponding to that identifier.
108
+ * This is useful for performance-sensitive scenarios involving many nodes with identifiers that need to be compactly retained in memory or used for efficient lookup.
109
+ *
110
+ * If the node's identifier is any other user-provided string, then this will return that string.
111
+ *
112
+ * If the node has no identifier (that is, it has no {@link SchemaFactory.identifier | identifier} field), then this returns `undefined`.
113
+ *
114
+ * If the node has more than one identifier, then this will throw an error.
115
+ *
116
+ * The returned integer must not be serialized or preserved outside of the current process.
117
+ * Its lifetime is that of the current in-memory instance of the FF container for this client, and it is not guaranteed to be unique or stable outside of that context.
118
+ * The same node's identifier may, for example, be different across multiple sessions for the same client and document, or different across two clients in the same session.
109
119
  */
110
120
  shortId(node: TreeNode): number | string | undefined;
111
121
  }
@@ -188,18 +198,26 @@ export const treeNodeApi: TreeNodeApi = {
188
198
  },
189
199
  shortId(node: TreeNode): number | string | undefined {
190
200
  const flexNode = getFlexNode(node);
201
+ let shortId: number | string | undefined;
191
202
  for (const field of flexNode.boxedIterator()) {
192
203
  if (field.schema.kind === FieldKinds.identifier) {
204
+ if (shortId !== undefined) {
205
+ throw new UsageError(
206
+ "shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.",
207
+ );
208
+ }
193
209
  const identifier = field.boxedAt(0);
194
210
  assert(identifier !== undefined, 0x927 /* The identifier must exist */);
195
211
  const identifierValue = identifier.value as string;
196
212
  const localNodeKey =
197
213
  identifier.context.nodeKeyManager.tryLocalizeNodeKey(identifierValue);
198
- return localNodeKey !== undefined
199
- ? extractFromOpaque(localNodeKey)
200
- : identifierValue;
214
+
215
+ shortId =
216
+ localNodeKey !== undefined ? extractFromOpaque(localNodeKey) : identifierValue;
201
217
  }
202
218
  }
219
+
220
+ return shortId;
203
221
  },
204
222
  };
205
223
 
@@ -6,7 +6,7 @@
6
6
  import type { ErasedType } from "@fluidframework/core-interfaces";
7
7
  import { assert } from "@fluidframework/core-utils/internal";
8
8
 
9
- import { type TreeNodeSchema, type WithType, type } from "./schemaTypes.js";
9
+ import { NodeKind, type TreeNodeSchema, type WithType, type } from "./schemaTypes.js";
10
10
  import {
11
11
  type FlexTreeNode,
12
12
  type MapTreeNode,
@@ -19,6 +19,7 @@ import { UsageError } from "@fluidframework/telemetry-utils/internal";
19
19
  import { getFlexSchema } from "./toFlexSchema.js";
20
20
  import { fail } from "../util/index.js";
21
21
  import { setFlexNode } from "./proxyBinding.js";
22
+ import { tryGetSchema } from "./treeNodeApi.js";
22
23
 
23
24
  /**
24
25
  * Type alias to document which values are un-hydrated.
@@ -32,7 +33,7 @@ import { setFlexNode } from "./proxyBinding.js";
32
33
  export type Unhydrated<T> = T;
33
34
 
34
35
  /**
35
- * A non-leaf SharedTree node. Includes objects, arrays, and maps.
36
+ * A non-{@link NodeKind.Leaf|leaf} SharedTree node. Includes objects, arrays, and maps.
36
37
  *
37
38
  * @remarks
38
39
  * Base type which all nodes implement.
@@ -50,11 +51,8 @@ export type Unhydrated<T> = T;
50
51
  *
51
52
  * Not all node implementations include this in their prototype chain (some hide it with a proxy),
52
53
  * and thus cause the default/built in `instanceof` to return false despite our type checking and all other APIs treating them as TreeNodes.
53
- * This results in the runtime and compile time behavior of `instanceof` differing.
54
- * TypeScript 5.3 allows altering the compile time behavior of `instanceof`.
55
- * The runtime behavior can be changed by implementing `Symbol.hasInstance`.
56
- * One of those approaches could be used to resolve this inconsistency,
57
- * but for now the type-only export prevents use of `instanceof` avoiding this problem in the public API.
54
+ * This class provides a custom `Symbol.hasInstance` to fix `instanceof` for this class and all classes extending it.
55
+ * For now the type-only export prevents use of `instanceof` on this class (but allows it in subclasses like schema classes).
58
56
  * @public
59
57
  */
60
58
  export abstract class TreeNode implements WithType {
@@ -80,7 +78,7 @@ export abstract class TreeNode implements WithType {
80
78
  * Another option would be to use a symbol (possibly as a private field).
81
79
  * That approach ran into some strange difficulties causing SchemaFactory to fail to compile, and was not investigated further.
82
80
  *
83
- * The [type] symbol here provides a lot of the value this private brand does, but is not all of it:
81
+ * The [type] symbol provides a lot of the value this private brand does, but is not all of it:
84
82
  * someone could manually (or via Intellisense auto-implement completion, or in response to a type error)
85
83
  * make an object literal with the [type] field and pass it off as a node: this private brand prevents that.
86
84
  */
@@ -93,13 +91,63 @@ export abstract class TreeNode implements WithType {
93
91
  */
94
92
  public abstract get [type](): string;
95
93
 
94
+ /**
95
+ * Provides `instanceof` support for testing if a value is a `TreeNode`.
96
+ * @remarks
97
+ * For more options, like including leaf values or narrowing to collections of schema, use `is` or `schema` from {@link TreeNodeApi}.
98
+ * @privateRemarks
99
+ * Due to type-only export, this functionality is not available outside the package.
100
+ */
101
+ public static [Symbol.hasInstance](value: unknown): value is TreeNode;
102
+
103
+ /**
104
+ * Provides `instanceof` support for all schema classes with public constructors.
105
+ * @remarks
106
+ * For more options, like including leaf values or narrowing to collections of schema, use `is` or `schema` from {@link TreeNodeApi}.
107
+ * @privateRemarks
108
+ * Despite type-only export, this functionality is available outside the package since it is inherited by subclasses.
109
+ */
110
+ public static [Symbol.hasInstance]<TSchema extends abstract new (...args: any[]) => TreeNode>(
111
+ this: TSchema,
112
+ value: unknown,
113
+ ): value is InstanceType<TSchema>;
114
+
115
+ public static [Symbol.hasInstance](this: { prototype: object }, value: unknown): boolean {
116
+ const schema = tryGetSchema(value);
117
+
118
+ if (schema === undefined || schema.kind === NodeKind.Leaf) {
119
+ return false;
120
+ }
121
+
122
+ assert("prototype" in schema, "expected class based schema");
123
+ return inPrototypeChain(schema.prototype, this.prototype);
124
+ }
125
+
96
126
  protected constructor() {
97
- if (!(this instanceof TreeNodeValid)) {
127
+ if (!inPrototypeChain(Reflect.getPrototypeOf(this), TreeNodeValid.prototype)) {
98
128
  throw new UsageError("TreeNodes must extend schema classes created by SchemaFactory");
99
129
  }
100
130
  }
101
131
  }
102
132
 
133
+ /**
134
+ * Check if the prototype derived's prototype chain contains `base`.
135
+ * @param derived - prototype to check
136
+ * @param base - prototype to search for
137
+ * @returns true iff `base` is in the prototype chain starting at `derived`.
138
+ */
139
+ // eslint-disable-next-line @rushstack/no-new-null
140
+ export function inPrototypeChain(derived: object | null, base: object): boolean {
141
+ let checking = derived;
142
+ while (checking !== null) {
143
+ if (base === checking) {
144
+ return true;
145
+ }
146
+ checking = Reflect.getPrototypeOf(checking);
147
+ }
148
+ return false;
149
+ }
150
+
103
151
  /**
104
152
  * Class which all {@link TreeNode}s must extend.
105
153
  * Since this is not exported, it allows robust detection of attempts to create TreeNodes which do not go through SchemaFactory which is the only place which exposes classes that extend this.
package/tsdoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
3
+ "extends": ["../../../common/build/build-common/tsdoc-base.json"]
4
+ }