@fluidframework/tree 2.1.0-276985 → 2.1.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 (583) hide show
  1. package/.eslintrc.cjs +7 -0
  2. package/.vscode/Tree.code-workspace +9 -2
  3. package/CHANGELOG.md +38 -0
  4. package/README.md +55 -12
  5. package/api-report/tree.alpha.api.md +2 -1
  6. package/api-report/tree.beta.api.md +2 -1
  7. package/api-report/tree.public.api.md +2 -1
  8. package/beta.d.ts +1 -1
  9. package/dist/beta.d.ts +1 -1
  10. package/dist/core/forest/editableForest.d.ts +6 -3
  11. package/dist/core/forest/editableForest.d.ts.map +1 -1
  12. package/dist/core/forest/editableForest.js +16 -4
  13. package/dist/core/forest/editableForest.js.map +1 -1
  14. package/dist/core/index.d.ts +1 -1
  15. package/dist/core/index.d.ts.map +1 -1
  16. package/dist/core/index.js +3 -1
  17. package/dist/core/index.js.map +1 -1
  18. package/dist/core/rebase/index.d.ts +1 -1
  19. package/dist/core/rebase/index.d.ts.map +1 -1
  20. package/dist/core/rebase/index.js +3 -1
  21. package/dist/core/rebase/index.js.map +1 -1
  22. package/dist/core/rebase/types.d.ts +2 -0
  23. package/dist/core/rebase/types.d.ts.map +1 -1
  24. package/dist/core/rebase/types.js +9 -1
  25. package/dist/core/rebase/types.js.map +1 -1
  26. package/dist/core/tree/anchorSet.d.ts +1 -0
  27. package/dist/core/tree/anchorSet.d.ts.map +1 -1
  28. package/dist/core/tree/anchorSet.js +13 -0
  29. package/dist/core/tree/anchorSet.js.map +1 -1
  30. package/dist/core/tree/detachedFieldIndex.d.ts +48 -11
  31. package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
  32. package/dist/core/tree/detachedFieldIndex.js +144 -20
  33. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  34. package/dist/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
  35. package/dist/core/tree/detachedFieldIndexCodec.js +13 -4
  36. package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
  37. package/dist/core/tree/detachedFieldIndexFormat.d.ts +1 -1
  38. package/dist/core/tree/detachedFieldIndexFormat.d.ts.map +1 -1
  39. package/dist/core/tree/detachedFieldIndexFormat.js.map +1 -1
  40. package/dist/core/tree/detachedFieldIndexTypes.d.ts +39 -4
  41. package/dist/core/tree/detachedFieldIndexTypes.d.ts.map +1 -1
  42. package/dist/core/tree/detachedFieldIndexTypes.js.map +1 -1
  43. package/dist/core/tree/index.d.ts +2 -1
  44. package/dist/core/tree/index.d.ts.map +1 -1
  45. package/dist/core/tree/index.js.map +1 -1
  46. package/dist/core/tree/visitDelta.d.ts +3 -1
  47. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  48. package/dist/core/tree/visitDelta.js +31 -15
  49. package/dist/core/tree/visitDelta.js.map +1 -1
  50. package/dist/core/tree/visitorUtils.d.ts +3 -3
  51. package/dist/core/tree/visitorUtils.d.ts.map +1 -1
  52. package/dist/core/tree/visitorUtils.js +4 -4
  53. package/dist/core/tree/visitorUtils.js.map +1 -1
  54. package/dist/events/events.d.ts +4 -1
  55. package/dist/events/events.d.ts.map +1 -1
  56. package/dist/events/events.js.map +1 -1
  57. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +1 -1
  58. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  59. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  60. package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -0
  61. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  62. package/dist/feature-libraries/editableTreeBinder.js +1 -1
  63. package/dist/feature-libraries/editableTreeBinder.js.map +1 -1
  64. package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts +1 -10
  65. package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
  66. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +0 -72
  67. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  68. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -51
  69. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  70. package/dist/feature-libraries/flex-tree/flexTreeTypes.js +0 -2
  71. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  72. package/dist/feature-libraries/flex-tree/index.d.ts +3 -2
  73. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  74. package/dist/feature-libraries/flex-tree/index.js +5 -1
  75. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  76. package/dist/feature-libraries/flex-tree/lazyEntity.d.ts +1 -2
  77. package/dist/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
  78. package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  79. package/dist/feature-libraries/flex-tree/lazyField.d.ts +1 -6
  80. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  81. package/dist/feature-libraries/flex-tree/lazyField.js +11 -32
  82. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  83. package/dist/feature-libraries/flex-tree/lazyNode.d.ts +1 -5
  84. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  85. package/dist/feature-libraries/flex-tree/lazyNode.js +0 -30
  86. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  87. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  88. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -1
  89. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  90. package/dist/feature-libraries/index.d.ts +3 -3
  91. package/dist/feature-libraries/index.d.ts.map +1 -1
  92. package/dist/feature-libraries/index.js +6 -3
  93. package/dist/feature-libraries/index.js.map +1 -1
  94. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +11 -0
  95. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  96. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  97. package/dist/feature-libraries/modular-schema/discrepancies.d.ts +96 -0
  98. package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -0
  99. package/dist/feature-libraries/modular-schema/discrepancies.js +264 -0
  100. package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -0
  101. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +9 -2
  102. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  103. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  104. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  105. package/dist/feature-libraries/modular-schema/genericFieldKind.js +3 -0
  106. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  107. package/dist/feature-libraries/modular-schema/index.d.ts +2 -1
  108. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  109. package/dist/feature-libraries/modular-schema/index.js +3 -1
  110. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  111. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  112. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +42 -26
  113. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  114. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +51 -2
  115. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  116. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +827 -245
  117. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  118. package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  119. package/dist/feature-libraries/modular-schema/modularChangeFormat.js +2 -0
  120. package/dist/feature-libraries/modular-schema/modularChangeFormat.js.map +1 -1
  121. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +44 -1
  122. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  123. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  124. package/dist/feature-libraries/node-key/index.d.ts +0 -1
  125. package/dist/feature-libraries/node-key/index.d.ts.map +1 -1
  126. package/dist/feature-libraries/node-key/index.js +1 -3
  127. package/dist/feature-libraries/node-key/index.js.map +1 -1
  128. package/dist/feature-libraries/object-forest/objectForest.d.ts +3 -2
  129. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  130. package/dist/feature-libraries/object-forest/objectForest.js +5 -4
  131. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  132. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  133. package/dist/feature-libraries/optional-field/optionalField.js +1 -0
  134. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  135. package/dist/feature-libraries/sequence-field/index.d.ts +1 -1
  136. package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
  137. package/dist/feature-libraries/sequence-field/index.js +1 -2
  138. package/dist/feature-libraries/sequence-field/index.js.map +1 -1
  139. package/dist/feature-libraries/sequence-field/invert.js +1 -1
  140. package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
  141. package/dist/feature-libraries/sequence-field/rebase.js +6 -1
  142. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  143. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  144. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +1 -0
  145. package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  146. package/dist/feature-libraries/sequence-field/utils.d.ts +2 -17
  147. package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  148. package/dist/feature-libraries/sequence-field/utils.js +31 -39
  149. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  150. package/dist/feature-libraries/typed-schema/typedTreeSchema.d.ts +1 -0
  151. package/dist/feature-libraries/typed-schema/typedTreeSchema.d.ts.map +1 -1
  152. package/dist/feature-libraries/typed-schema/typedTreeSchema.js +2 -0
  153. package/dist/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  154. package/dist/index.d.ts +1 -1
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js.map +1 -1
  157. package/dist/packageVersion.d.ts +1 -1
  158. package/dist/packageVersion.d.ts.map +1 -1
  159. package/dist/packageVersion.js +1 -1
  160. package/dist/packageVersion.js.map +1 -1
  161. package/dist/public.d.ts +1 -1
  162. package/dist/shared-tree/schematizingTreeView.d.ts +4 -2
  163. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  164. package/dist/shared-tree/schematizingTreeView.js +240 -184
  165. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  166. package/dist/shared-tree/sharedTree.d.ts +5 -1
  167. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  168. package/dist/shared-tree/sharedTree.js +157 -90
  169. package/dist/shared-tree/sharedTree.js.map +1 -1
  170. package/dist/shared-tree/sharedTreeChangeEnricher.js +1 -1
  171. package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  172. package/dist/shared-tree/treeApi.js +1 -1
  173. package/dist/shared-tree/treeApi.js.map +1 -1
  174. package/dist/shared-tree/treeCheckout.d.ts +10 -1
  175. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  176. package/dist/shared-tree/treeCheckout.js +47 -3
  177. package/dist/shared-tree/treeCheckout.js.map +1 -1
  178. package/dist/shared-tree/treeView.d.ts.map +1 -1
  179. package/dist/shared-tree/treeView.js +7 -3
  180. package/dist/shared-tree/treeView.js.map +1 -1
  181. package/dist/shared-tree-core/branch.d.ts +6 -0
  182. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  183. package/dist/shared-tree-core/branch.js +3 -0
  184. package/dist/shared-tree-core/branch.js.map +1 -1
  185. package/dist/shared-tree-core/sharedTreeCore.d.ts +8 -6
  186. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  187. package/dist/shared-tree-core/sharedTreeCore.js +271 -209
  188. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  189. package/dist/simple-tree/arrayNode.d.ts +4 -0
  190. package/dist/simple-tree/arrayNode.d.ts.map +1 -1
  191. package/dist/simple-tree/arrayNode.js +36 -19
  192. package/dist/simple-tree/arrayNode.js.map +1 -1
  193. package/dist/simple-tree/index.d.ts +3 -3
  194. package/dist/simple-tree/index.d.ts.map +1 -1
  195. package/dist/simple-tree/index.js +2 -1
  196. package/dist/simple-tree/index.js.map +1 -1
  197. package/dist/simple-tree/leafNodeSchema.d.ts +22 -1
  198. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  199. package/dist/simple-tree/leafNodeSchema.js +2 -1
  200. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  201. package/dist/simple-tree/mapNode.d.ts.map +1 -1
  202. package/dist/simple-tree/mapNode.js.map +1 -1
  203. package/dist/simple-tree/objectNode.d.ts.map +1 -1
  204. package/dist/simple-tree/objectNode.js +2 -1
  205. package/dist/simple-tree/objectNode.js.map +1 -1
  206. package/dist/simple-tree/proxies.d.ts.map +1 -1
  207. package/dist/simple-tree/proxies.js +9 -25
  208. package/dist/simple-tree/proxies.js.map +1 -1
  209. package/dist/simple-tree/proxyBinding.d.ts +4 -0
  210. package/dist/simple-tree/proxyBinding.d.ts.map +1 -1
  211. package/dist/simple-tree/proxyBinding.js +23 -1
  212. package/dist/simple-tree/proxyBinding.js.map +1 -1
  213. package/dist/simple-tree/schemaFactory.d.ts +16 -1
  214. package/dist/simple-tree/schemaFactory.d.ts.map +1 -1
  215. package/dist/simple-tree/schemaFactory.js +32 -4
  216. package/dist/simple-tree/schemaFactory.js.map +1 -1
  217. package/dist/simple-tree/schemaTypes.d.ts +36 -1
  218. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  219. package/dist/simple-tree/schemaTypes.js.map +1 -1
  220. package/dist/simple-tree/toFlexSchema.d.ts +2 -2
  221. package/dist/simple-tree/toFlexSchema.d.ts.map +1 -1
  222. package/dist/simple-tree/toFlexSchema.js +3 -2
  223. package/dist/simple-tree/toFlexSchema.js.map +1 -1
  224. package/dist/simple-tree/tree.d.ts +4 -1
  225. package/dist/simple-tree/tree.d.ts.map +1 -1
  226. package/dist/simple-tree/tree.js +48 -1
  227. package/dist/simple-tree/tree.js.map +1 -1
  228. package/dist/simple-tree/treeNodeApi.d.ts +2 -75
  229. package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
  230. package/dist/simple-tree/treeNodeApi.js +17 -25
  231. package/dist/simple-tree/treeNodeApi.js.map +1 -1
  232. package/dist/simple-tree/treeNodeKernel.d.ts +26 -0
  233. package/dist/simple-tree/treeNodeKernel.d.ts.map +1 -0
  234. package/dist/simple-tree/treeNodeKernel.js +83 -0
  235. package/dist/simple-tree/treeNodeKernel.js.map +1 -0
  236. package/dist/simple-tree/types.d.ts +95 -3
  237. package/dist/simple-tree/types.d.ts.map +1 -1
  238. package/dist/simple-tree/types.js +120 -21
  239. package/dist/simple-tree/types.js.map +1 -1
  240. package/dist/util/breakable.d.ts +83 -0
  241. package/dist/util/breakable.d.ts.map +1 -0
  242. package/dist/util/breakable.js +178 -0
  243. package/dist/util/breakable.js.map +1 -0
  244. package/dist/util/index.d.ts +3 -2
  245. package/dist/util/index.d.ts.map +1 -1
  246. package/dist/util/index.js +9 -2
  247. package/dist/util/index.js.map +1 -1
  248. package/dist/util/nestedMap.d.ts +17 -3
  249. package/dist/util/nestedMap.d.ts.map +1 -1
  250. package/dist/util/nestedMap.js +21 -1
  251. package/dist/util/nestedMap.js.map +1 -1
  252. package/dist/util/utils.d.ts +7 -0
  253. package/dist/util/utils.d.ts.map +1 -1
  254. package/dist/util/utils.js +15 -1
  255. package/dist/util/utils.js.map +1 -1
  256. package/internal.d.ts +1 -1
  257. package/lib/beta.d.ts +1 -1
  258. package/lib/core/forest/editableForest.d.ts +6 -3
  259. package/lib/core/forest/editableForest.d.ts.map +1 -1
  260. package/lib/core/forest/editableForest.js +17 -5
  261. package/lib/core/forest/editableForest.js.map +1 -1
  262. package/lib/core/index.d.ts +1 -1
  263. package/lib/core/index.d.ts.map +1 -1
  264. package/lib/core/index.js +1 -1
  265. package/lib/core/index.js.map +1 -1
  266. package/lib/core/rebase/index.d.ts +1 -1
  267. package/lib/core/rebase/index.d.ts.map +1 -1
  268. package/lib/core/rebase/index.js +1 -1
  269. package/lib/core/rebase/index.js.map +1 -1
  270. package/lib/core/rebase/types.d.ts +2 -0
  271. package/lib/core/rebase/types.d.ts.map +1 -1
  272. package/lib/core/rebase/types.js +7 -1
  273. package/lib/core/rebase/types.js.map +1 -1
  274. package/lib/core/tree/anchorSet.d.ts +1 -0
  275. package/lib/core/tree/anchorSet.d.ts.map +1 -1
  276. package/lib/core/tree/anchorSet.js +13 -0
  277. package/lib/core/tree/anchorSet.js.map +1 -1
  278. package/lib/core/tree/detachedFieldIndex.d.ts +48 -11
  279. package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
  280. package/lib/core/tree/detachedFieldIndex.js +145 -21
  281. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  282. package/lib/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
  283. package/lib/core/tree/detachedFieldIndexCodec.js +13 -4
  284. package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
  285. package/lib/core/tree/detachedFieldIndexFormat.d.ts +1 -1
  286. package/lib/core/tree/detachedFieldIndexFormat.d.ts.map +1 -1
  287. package/lib/core/tree/detachedFieldIndexFormat.js.map +1 -1
  288. package/lib/core/tree/detachedFieldIndexTypes.d.ts +39 -4
  289. package/lib/core/tree/detachedFieldIndexTypes.d.ts.map +1 -1
  290. package/lib/core/tree/detachedFieldIndexTypes.js.map +1 -1
  291. package/lib/core/tree/index.d.ts +2 -1
  292. package/lib/core/tree/index.d.ts.map +1 -1
  293. package/lib/core/tree/index.js.map +1 -1
  294. package/lib/core/tree/visitDelta.d.ts +3 -1
  295. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  296. package/lib/core/tree/visitDelta.js +31 -15
  297. package/lib/core/tree/visitDelta.js.map +1 -1
  298. package/lib/core/tree/visitorUtils.d.ts +3 -3
  299. package/lib/core/tree/visitorUtils.d.ts.map +1 -1
  300. package/lib/core/tree/visitorUtils.js +4 -4
  301. package/lib/core/tree/visitorUtils.js.map +1 -1
  302. package/lib/events/events.d.ts +4 -1
  303. package/lib/events/events.d.ts.map +1 -1
  304. package/lib/events/events.js.map +1 -1
  305. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +1 -1
  306. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  307. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  308. package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -0
  309. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  310. package/lib/feature-libraries/editableTreeBinder.js +1 -1
  311. package/lib/feature-libraries/editableTreeBinder.js.map +1 -1
  312. package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts +1 -10
  313. package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
  314. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +2 -74
  315. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  316. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -51
  317. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
  318. package/lib/feature-libraries/flex-tree/flexTreeTypes.js +0 -2
  319. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  320. package/lib/feature-libraries/flex-tree/index.d.ts +3 -2
  321. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  322. package/lib/feature-libraries/flex-tree/index.js +2 -1
  323. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  324. package/lib/feature-libraries/flex-tree/lazyEntity.d.ts +1 -2
  325. package/lib/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
  326. package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  327. package/lib/feature-libraries/flex-tree/lazyField.d.ts +1 -6
  328. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  329. package/lib/feature-libraries/flex-tree/lazyField.js +13 -34
  330. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  331. package/lib/feature-libraries/flex-tree/lazyNode.d.ts +1 -5
  332. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  333. package/lib/feature-libraries/flex-tree/lazyNode.js +3 -33
  334. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  335. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  336. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -1
  337. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  338. package/lib/feature-libraries/index.d.ts +3 -3
  339. package/lib/feature-libraries/index.d.ts.map +1 -1
  340. package/lib/feature-libraries/index.js +3 -3
  341. package/lib/feature-libraries/index.js.map +1 -1
  342. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +11 -0
  343. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  344. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  345. package/lib/feature-libraries/modular-schema/discrepancies.d.ts +96 -0
  346. package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -0
  347. package/lib/feature-libraries/modular-schema/discrepancies.js +260 -0
  348. package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -0
  349. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +9 -2
  350. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  351. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  352. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  353. package/lib/feature-libraries/modular-schema/genericFieldKind.js +3 -0
  354. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  355. package/lib/feature-libraries/modular-schema/index.d.ts +2 -1
  356. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  357. package/lib/feature-libraries/modular-schema/index.js +1 -0
  358. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  359. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  360. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +42 -26
  361. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  362. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +51 -2
  363. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  364. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +826 -247
  365. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  366. package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
  367. package/lib/feature-libraries/modular-schema/modularChangeFormat.js +2 -0
  368. package/lib/feature-libraries/modular-schema/modularChangeFormat.js.map +1 -1
  369. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +44 -1
  370. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  371. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  372. package/lib/feature-libraries/node-key/index.d.ts +0 -1
  373. package/lib/feature-libraries/node-key/index.d.ts.map +1 -1
  374. package/lib/feature-libraries/node-key/index.js +0 -1
  375. package/lib/feature-libraries/node-key/index.js.map +1 -1
  376. package/lib/feature-libraries/object-forest/objectForest.d.ts +3 -2
  377. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  378. package/lib/feature-libraries/object-forest/objectForest.js +5 -4
  379. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  380. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  381. package/lib/feature-libraries/optional-field/optionalField.js +1 -0
  382. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  383. package/lib/feature-libraries/sequence-field/index.d.ts +1 -1
  384. package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
  385. package/lib/feature-libraries/sequence-field/index.js +1 -1
  386. package/lib/feature-libraries/sequence-field/index.js.map +1 -1
  387. package/lib/feature-libraries/sequence-field/invert.js +1 -1
  388. package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
  389. package/lib/feature-libraries/sequence-field/rebase.js +6 -1
  390. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  391. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
  392. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -1
  393. package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
  394. package/lib/feature-libraries/sequence-field/utils.d.ts +2 -17
  395. package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
  396. package/lib/feature-libraries/sequence-field/utils.js +31 -39
  397. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  398. package/lib/feature-libraries/typed-schema/typedTreeSchema.d.ts +1 -0
  399. package/lib/feature-libraries/typed-schema/typedTreeSchema.d.ts.map +1 -1
  400. package/lib/feature-libraries/typed-schema/typedTreeSchema.js +4 -2
  401. package/lib/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  402. package/lib/index.d.ts +1 -1
  403. package/lib/index.d.ts.map +1 -1
  404. package/lib/index.js.map +1 -1
  405. package/lib/packageVersion.d.ts +1 -1
  406. package/lib/packageVersion.d.ts.map +1 -1
  407. package/lib/packageVersion.js +1 -1
  408. package/lib/packageVersion.js.map +1 -1
  409. package/lib/public.d.ts +1 -1
  410. package/lib/shared-tree/schematizingTreeView.d.ts +4 -2
  411. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  412. package/lib/shared-tree/schematizingTreeView.js +242 -185
  413. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  414. package/lib/shared-tree/sharedTree.d.ts +5 -1
  415. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  416. package/lib/shared-tree/sharedTree.js +158 -90
  417. package/lib/shared-tree/sharedTree.js.map +1 -1
  418. package/lib/shared-tree/sharedTreeChangeEnricher.js +1 -1
  419. package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  420. package/lib/shared-tree/treeApi.js +1 -1
  421. package/lib/shared-tree/treeApi.js.map +1 -1
  422. package/lib/shared-tree/treeCheckout.d.ts +10 -1
  423. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  424. package/lib/shared-tree/treeCheckout.js +47 -3
  425. package/lib/shared-tree/treeCheckout.js.map +1 -1
  426. package/lib/shared-tree/treeView.d.ts.map +1 -1
  427. package/lib/shared-tree/treeView.js +4 -0
  428. package/lib/shared-tree/treeView.js.map +1 -1
  429. package/lib/shared-tree-core/branch.d.ts +6 -0
  430. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  431. package/lib/shared-tree-core/branch.js +3 -0
  432. package/lib/shared-tree-core/branch.js.map +1 -1
  433. package/lib/shared-tree-core/sharedTreeCore.d.ts +8 -6
  434. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  435. package/lib/shared-tree-core/sharedTreeCore.js +273 -210
  436. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  437. package/lib/simple-tree/arrayNode.d.ts +4 -0
  438. package/lib/simple-tree/arrayNode.d.ts.map +1 -1
  439. package/lib/simple-tree/arrayNode.js +39 -22
  440. package/lib/simple-tree/arrayNode.js.map +1 -1
  441. package/lib/simple-tree/index.d.ts +3 -3
  442. package/lib/simple-tree/index.d.ts.map +1 -1
  443. package/lib/simple-tree/index.js +1 -1
  444. package/lib/simple-tree/index.js.map +1 -1
  445. package/lib/simple-tree/leafNodeSchema.d.ts +22 -1
  446. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  447. package/lib/simple-tree/leafNodeSchema.js +1 -1
  448. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  449. package/lib/simple-tree/mapNode.d.ts.map +1 -1
  450. package/lib/simple-tree/mapNode.js.map +1 -1
  451. package/lib/simple-tree/objectNode.d.ts.map +1 -1
  452. package/lib/simple-tree/objectNode.js +3 -2
  453. package/lib/simple-tree/objectNode.js.map +1 -1
  454. package/lib/simple-tree/proxies.d.ts.map +1 -1
  455. package/lib/simple-tree/proxies.js +9 -25
  456. package/lib/simple-tree/proxies.js.map +1 -1
  457. package/lib/simple-tree/proxyBinding.d.ts +4 -0
  458. package/lib/simple-tree/proxyBinding.d.ts.map +1 -1
  459. package/lib/simple-tree/proxyBinding.js +19 -0
  460. package/lib/simple-tree/proxyBinding.js.map +1 -1
  461. package/lib/simple-tree/schemaFactory.d.ts +16 -1
  462. package/lib/simple-tree/schemaFactory.d.ts.map +1 -1
  463. package/lib/simple-tree/schemaFactory.js +30 -3
  464. package/lib/simple-tree/schemaFactory.js.map +1 -1
  465. package/lib/simple-tree/schemaTypes.d.ts +36 -1
  466. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  467. package/lib/simple-tree/schemaTypes.js.map +1 -1
  468. package/lib/simple-tree/toFlexSchema.d.ts +2 -2
  469. package/lib/simple-tree/toFlexSchema.d.ts.map +1 -1
  470. package/lib/simple-tree/toFlexSchema.js +3 -2
  471. package/lib/simple-tree/toFlexSchema.js.map +1 -1
  472. package/lib/simple-tree/tree.d.ts +4 -1
  473. package/lib/simple-tree/tree.d.ts.map +1 -1
  474. package/lib/simple-tree/tree.js +44 -0
  475. package/lib/simple-tree/tree.js.map +1 -1
  476. package/lib/simple-tree/treeNodeApi.d.ts +2 -75
  477. package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
  478. package/lib/simple-tree/treeNodeApi.js +20 -28
  479. package/lib/simple-tree/treeNodeApi.js.map +1 -1
  480. package/lib/simple-tree/treeNodeKernel.d.ts +26 -0
  481. package/lib/simple-tree/treeNodeKernel.d.ts.map +1 -0
  482. package/lib/simple-tree/treeNodeKernel.js +79 -0
  483. package/lib/simple-tree/treeNodeKernel.js.map +1 -0
  484. package/lib/simple-tree/types.d.ts +95 -3
  485. package/lib/simple-tree/types.d.ts.map +1 -1
  486. package/lib/simple-tree/types.js +121 -22
  487. package/lib/simple-tree/types.js.map +1 -1
  488. package/lib/util/breakable.d.ts +83 -0
  489. package/lib/util/breakable.d.ts.map +1 -0
  490. package/lib/util/breakable.js +171 -0
  491. package/lib/util/breakable.js.map +1 -0
  492. package/lib/util/index.d.ts +3 -2
  493. package/lib/util/index.d.ts.map +1 -1
  494. package/lib/util/index.js +3 -2
  495. package/lib/util/index.js.map +1 -1
  496. package/lib/util/nestedMap.d.ts +17 -3
  497. package/lib/util/nestedMap.d.ts.map +1 -1
  498. package/lib/util/nestedMap.js +19 -0
  499. package/lib/util/nestedMap.js.map +1 -1
  500. package/lib/util/utils.d.ts +7 -0
  501. package/lib/util/utils.d.ts.map +1 -1
  502. package/lib/util/utils.js +13 -0
  503. package/lib/util/utils.js.map +1 -1
  504. package/package.json +29 -27
  505. package/src/core/forest/editableForest.ts +25 -4
  506. package/src/core/index.ts +2 -0
  507. package/src/core/rebase/index.ts +2 -0
  508. package/src/core/rebase/types.ts +17 -0
  509. package/src/core/tree/anchorSet.ts +14 -0
  510. package/src/core/tree/detachedFieldIndex.ts +217 -35
  511. package/src/core/tree/detachedFieldIndexCodec.ts +17 -8
  512. package/src/core/tree/detachedFieldIndexFormat.ts +1 -1
  513. package/src/core/tree/detachedFieldIndexTypes.ts +41 -5
  514. package/src/core/tree/index.ts +2 -1
  515. package/src/core/tree/visitDelta.ts +58 -16
  516. package/src/core/tree/visitorUtils.ts +7 -4
  517. package/src/events/events.ts +4 -2
  518. package/src/feature-libraries/default-schema/defaultEditBuilder.ts +1 -1
  519. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -0
  520. package/src/feature-libraries/editableTreeBinder.ts +1 -1
  521. package/src/feature-libraries/flex-map-tree/mapTreeNode.ts +1 -95
  522. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +0 -62
  523. package/src/feature-libraries/flex-tree/index.ts +7 -2
  524. package/src/feature-libraries/flex-tree/lazyEntity.ts +0 -3
  525. package/src/feature-libraries/flex-tree/lazyField.ts +15 -47
  526. package/src/feature-libraries/flex-tree/lazyNode.ts +1 -48
  527. package/src/feature-libraries/forest-summary/forestSummarizer.ts +1 -0
  528. package/src/feature-libraries/index.ts +4 -2
  529. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +18 -0
  530. package/src/feature-libraries/modular-schema/discrepancies.ts +395 -0
  531. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +10 -2
  532. package/src/feature-libraries/modular-schema/genericFieldKind.ts +3 -0
  533. package/src/feature-libraries/modular-schema/index.ts +2 -0
  534. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +81 -35
  535. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1521 -444
  536. package/src/feature-libraries/modular-schema/modularChangeFormat.ts +2 -0
  537. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +51 -0
  538. package/src/feature-libraries/node-key/index.ts +0 -1
  539. package/src/feature-libraries/object-forest/objectForest.ts +7 -3
  540. package/src/feature-libraries/optional-field/optionalField.ts +1 -0
  541. package/src/feature-libraries/sequence-field/index.ts +0 -2
  542. package/src/feature-libraries/sequence-field/invert.ts +1 -1
  543. package/src/feature-libraries/sequence-field/rebase.ts +7 -1
  544. package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +2 -1
  545. package/src/feature-libraries/sequence-field/utils.ts +37 -85
  546. package/src/feature-libraries/typed-schema/typedTreeSchema.ts +10 -0
  547. package/src/index.ts +0 -1
  548. package/src/packageVersion.ts +1 -1
  549. package/src/shared-tree/schematizingTreeView.ts +6 -2
  550. package/src/shared-tree/sharedTree.ts +12 -1
  551. package/src/shared-tree/sharedTreeChangeEnricher.ts +1 -1
  552. package/src/shared-tree/treeApi.ts +1 -1
  553. package/src/shared-tree/treeCheckout.ts +60 -5
  554. package/src/shared-tree/treeView.ts +5 -0
  555. package/src/shared-tree-core/branch.ts +10 -0
  556. package/src/shared-tree-core/sharedTreeCore.ts +25 -6
  557. package/src/simple-tree/arrayNode.ts +50 -23
  558. package/src/simple-tree/index.ts +3 -3
  559. package/src/simple-tree/leafNodeSchema.ts +1 -1
  560. package/src/simple-tree/mapNode.ts +2 -2
  561. package/src/simple-tree/objectNode.ts +9 -3
  562. package/src/simple-tree/proxies.ts +10 -33
  563. package/src/simple-tree/proxyBinding.ts +23 -0
  564. package/src/simple-tree/schemaFactory.ts +37 -2
  565. package/src/simple-tree/schemaTypes.ts +36 -1
  566. package/src/simple-tree/toFlexSchema.ts +5 -4
  567. package/src/simple-tree/tree.ts +68 -4
  568. package/src/simple-tree/treeNodeApi.ts +29 -111
  569. package/src/simple-tree/treeNodeKernel.ts +91 -0
  570. package/src/simple-tree/types.ts +292 -31
  571. package/src/util/breakable.ts +214 -0
  572. package/src/util/index.ts +11 -0
  573. package/src/util/nestedMap.ts +33 -3
  574. package/src/util/utils.ts +17 -0
  575. package/dist/feature-libraries/node-key/nodeKeyIndex.d.ts +0 -41
  576. package/dist/feature-libraries/node-key/nodeKeyIndex.d.ts.map +0 -1
  577. package/dist/feature-libraries/node-key/nodeKeyIndex.js +0 -101
  578. package/dist/feature-libraries/node-key/nodeKeyIndex.js.map +0 -1
  579. package/lib/feature-libraries/node-key/nodeKeyIndex.d.ts +0 -41
  580. package/lib/feature-libraries/node-key/nodeKeyIndex.d.ts.map +0 -1
  581. package/lib/feature-libraries/node-key/nodeKeyIndex.js +0 -97
  582. package/lib/feature-libraries/node-key/nodeKeyIndex.js.map +0 -1
  583. package/src/feature-libraries/node-key/nodeKeyIndex.ts +0 -132
@@ -1 +1 @@
1
- {"version":3,"file":"toFlexSchema.d.ts","sourceRoot":"","sources":["../../src/simple-tree/toFlexSchema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EACX,sBAAsB,EACtB,wBAAwB,EACxB,eAAe,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEN,KAAK,gBAAgB,EAGrB,eAAe,EAGf,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EAInB,MAAM,+BAA+B,CAAC;AAUvC,OAAO,EAGN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0CAA0C,EAE/C,KAAK,cAAc,EAGnB,MAAM,kBAAkB,CAAC;AAG1B;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,0CAA0C,EAChD,cAAc,EAAE,cAAc,EAC9B,sBAAsB,GAAE,eAAe,GAAG,SAAqB,GAC7D,sBAAsB,CAWxB;AAED,UAAU,UAAU;IACnB,MAAM,EAAE,MAAM,kBAAkB,CAAC;IACjC,QAAQ,EAAE,cAAc,CAAC;CACzB;AAED,KAAK,SAAS,GAAG,GAAG,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CA0BtE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,kBAAkB,CAGtE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC3B,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,mBAAmB,GACzB,eAAe,CAYjB;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,oBAAoB,GAC1B,gBAAgB,CAKlB;AAID;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,cAAc,GACpB,MAAM,kBAAkB,CAoF1B"}
1
+ {"version":3,"file":"toFlexSchema.d.ts","sourceRoot":"","sources":["../../src/simple-tree/toFlexSchema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EACX,sBAAsB,EACtB,wBAAwB,EACxB,eAAe,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEN,KAAK,gBAAgB,EAGrB,eAAe,EAGf,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EAInB,MAAM,+BAA+B,CAAC;AAUvC,OAAO,EAGN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0CAA0C,EAE/C,KAAK,cAAc,EAGnB,MAAM,kBAAkB,CAAC;AAG1B;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,0CAA0C,EAChD,cAAc,EAAE,cAAc,EAC9B,sBAAsB,GAAE,eAAe,GAAG,SAAqB,GAC7D,sBAAsB,CAWxB;AAED,UAAU,UAAU;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CAClC;AAED,KAAK,SAAS,GAAG,GAAG,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CA0BtE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,kBAAkB,CAGtE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC3B,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,mBAAmB,GACzB,eAAe,CAYjB;AAQD;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,oBAAoB,GAC1B,gBAAgB,CAKlB;AAID;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,cAAc,GACpB,MAAM,kBAAkB,CAoF1B"}
@@ -4,6 +4,7 @@
4
4
  */
5
5
  /* eslint-disable import/no-internal-modules */
6
6
  import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
7
+ import { UsageError } from "@fluidframework/telemetry-utils/internal";
7
8
  import { FieldKinds, FlexFieldNodeSchema, FlexFieldSchema, FlexMapNodeSchema, FlexObjectNodeSchema, TreeNodeSchemaBase, defaultSchemaPolicy, schemaIsLeaf, } from "../feature-libraries/index.js";
8
9
  import { normalizeFlexListEager } from "../feature-libraries/typed-schema/flexList.js";
9
10
  import { brand, fail, isReadonlyArray, mapIterable } from "../util/index.js";
@@ -103,8 +104,8 @@ export function convertNodeSchema(schemaMap, schema) {
103
104
  const fromMap = schemaMap.get(brand(schema.identifier));
104
105
  if (fromMap !== undefined) {
105
106
  if (fromMap.original !== schema) {
106
- // Use JSON.stringify to quote and escape string.
107
- throw new Error(`Multiple schema encountered with the identifier ${JSON.stringify(schema.identifier)}. Remove or rename them to avoid the collision.`);
107
+ // Use JSON.stringify to quote and escape identifier string.
108
+ throw new UsageError(`Multiple schema encountered with the identifier ${JSON.stringify(schema.identifier)}. Remove or rename them to avoid the collision.`);
108
109
  }
109
110
  return fromMap.toFlex;
110
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"toFlexSchema.js","sourceRoot":"","sources":["../../src/simple-tree/toFlexSchema.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable import/no-internal-modules */\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\n\nimport type {\n\tITreeCursorSynchronous,\n\tTreeNodeSchemaIdentifier,\n\tSchemaAndPolicy,\n} from \"../core/index.js\";\nimport {\n\tFieldKinds,\n\ttype FlexAllowedTypes,\n\ttype FlexFieldKind,\n\tFlexFieldNodeSchema,\n\tFlexFieldSchema,\n\tFlexMapNodeSchema,\n\tFlexObjectNodeSchema,\n\ttype FlexTreeNodeSchema,\n\ttype FlexTreeSchema,\n\ttype NodeKeyManager,\n\tTreeNodeSchemaBase,\n\tdefaultSchemaPolicy,\n\tschemaIsLeaf,\n} from \"../feature-libraries/index.js\";\nimport { normalizeFlexListEager } from \"../feature-libraries/typed-schema/flexList.js\";\nimport { brand, fail, isReadonlyArray, mapIterable } from \"../util/index.js\";\n\nimport type { InsertableContent } from \"./proxies.js\";\nimport {\n\tcachedFlexSchemaFromClassSchema,\n\tsetFlexSchemaFromClassSchema,\n\ttryGetSimpleNodeSchema,\n} from \"./schemaCaching.js\";\nimport {\n\tFieldKind,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype ImplicitFieldSchema,\n\ttype InsertableTreeNodeFromImplicitAllowedTypes,\n\tNodeKind,\n\ttype TreeNodeSchema,\n\tnormalizeFieldSchema,\n\tgetStoredKey,\n} from \"./schemaTypes.js\";\nimport { cursorFromNodeData } from \"./toMapTree.js\";\n\n/**\n * Returns a cursor (in nodes mode) for the root node.\n *\n * @privateRemarks\n * Ideally this would work on any node, not just the root,\n * and the schema would come from the unhydrated node.\n * For now though, this is the only case that's needed, and we do have the data to make it work, so this is fine.\n */\nexport function cursorFromUnhydratedRoot(\n\tschema: ImplicitFieldSchema,\n\ttree: InsertableTreeNodeFromImplicitAllowedTypes,\n\tnodeKeyManager: NodeKeyManager,\n\tschemaValidationPolicy: SchemaAndPolicy | undefined = undefined,\n): ITreeCursorSynchronous {\n\tconst data = tree as InsertableContent;\n\tconst normalizedFieldSchema = normalizeFieldSchema(schema);\n\treturn (\n\t\tcursorFromNodeData(\n\t\t\tdata,\n\t\t\tnormalizedFieldSchema.allowedTypes,\n\t\t\tnodeKeyManager,\n\t\t\tschemaValidationPolicy,\n\t\t) ?? fail(\"failed to decode tree\")\n\t);\n}\n\ninterface SchemaInfo {\n\ttoFlex: () => FlexTreeNodeSchema;\n\toriginal: TreeNodeSchema;\n}\n\ntype SchemaMap = Map<TreeNodeSchemaIdentifier, SchemaInfo>;\n\n/**\n * Generate a {@link FlexTreeSchema} with `root` as the root field.\n *\n * This also has the side effect of populating the cached view schema on the class-based schema.\n */\nexport function toFlexSchema(root: ImplicitFieldSchema): FlexTreeSchema {\n\tconst schemaMap: SchemaMap = new Map();\n\tconst field = convertField(schemaMap, root);\n\tconst nodeSchema = new Map(\n\t\tmapIterable(schemaMap, ([key, value]) => {\n\t\t\tconst schema = value.toFlex();\n\t\t\tconst classSchema = tryGetSimpleNodeSchema(schema);\n\t\t\tif (classSchema === undefined) {\n\t\t\t\tassert(schemaIsLeaf(schema), 0x83e /* invalid leaf */);\n\t\t\t} else {\n\t\t\t\tassert(\n\t\t\t\t\tcachedFlexSchemaFromClassSchema(classSchema) === schema,\n\t\t\t\t\t0x83f /* mismatched schema */,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn [key, schema];\n\t\t}),\n\t);\n\n\tconst typed: FlexTreeSchema = {\n\t\tnodeSchema,\n\t\tadapters: {},\n\t\trootFieldSchema: field,\n\t\tpolicy: defaultSchemaPolicy,\n\t};\n\treturn typed;\n}\n\n/**\n * Return a flex schema for the provided class schema.\n *\n * This also has the side effect of populating the cached view schema on the class based schema.\n */\nexport function getFlexSchema(root: TreeNodeSchema): FlexTreeNodeSchema {\n\tconst treeSchema = toFlexSchema(root);\n\treturn treeSchema.rootFieldSchema.monomorphicChildType ?? fail(\"root should be monomorphic\");\n}\n\n/**\n * Normalizes an {@link ImplicitFieldSchema} into a {@link TreeFieldSchema}.\n */\nexport function convertField(\n\tschemaMap: SchemaMap,\n\tschema: ImplicitFieldSchema,\n): FlexFieldSchema {\n\tlet kind: FlexFieldKind;\n\tlet types: ImplicitAllowedTypes;\n\tif (schema instanceof FieldSchema) {\n\t\tkind = convertFieldKind.get(schema.kind) ?? fail(\"Invalid field kind\");\n\t\ttypes = schema.allowedTypes;\n\t} else {\n\t\tkind = FieldKinds.required;\n\t\ttypes = schema;\n\t}\n\tconst allowedTypes = convertAllowedTypes(schemaMap, types);\n\treturn FlexFieldSchema.create(kind, allowedTypes);\n}\n\nconst convertFieldKind = new Map<FieldKind, FlexFieldKind>([\n\t[FieldKind.Optional, FieldKinds.optional],\n\t[FieldKind.Required, FieldKinds.required],\n\t[FieldKind.Identifier, FieldKinds.identifier],\n]);\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} into an {@link AllowedTypes}.\n */\nexport function convertAllowedTypes(\n\tschemaMap: SchemaMap,\n\tschema: ImplicitAllowedTypes,\n): FlexAllowedTypes {\n\tif (isReadonlyArray(schema)) {\n\t\treturn normalizeFlexListEager(schema).map((item) => convertNodeSchema(schemaMap, item));\n\t}\n\treturn [convertNodeSchema(schemaMap, schema)];\n}\n\nconst builder = { name: \"simple schema\" };\n\n/**\n * Converts a {@link TreeNodeSchema} into a {@link FlexTreeNodeSchema}.\n * Ensures all types reachable from `schema` are included in `schemaMap`.\n *\n * Return value (and entries in map) are lazy to allow recursive types to work.\n * This laziness does NOT extend to adding entries to `schemaMap`:\n * all referenced types are added to it before this function returns.\n */\nexport function convertNodeSchema(\n\tschemaMap: SchemaMap,\n\tschema: TreeNodeSchema,\n): () => FlexTreeNodeSchema {\n\tconst fromMap = schemaMap.get(brand(schema.identifier));\n\tif (fromMap !== undefined) {\n\t\tif (fromMap.original !== schema) {\n\t\t\t// Use JSON.stringify to quote and escape string.\n\t\t\tthrow new Error(\n\t\t\t\t`Multiple schema encountered with the identifier ${JSON.stringify(\n\t\t\t\t\tschema.identifier,\n\t\t\t\t)}. Remove or rename them to avoid the collision.`,\n\t\t\t);\n\t\t}\n\t\treturn fromMap.toFlex;\n\t}\n\n\tconst toFlex = (): FlexTreeNodeSchema => {\n\t\tlet out: FlexTreeNodeSchema;\n\t\tconst kind = schema.kind;\n\t\tswitch (kind) {\n\t\t\tcase NodeKind.Leaf: {\n\t\t\t\tconst cached =\n\t\t\t\t\tcachedFlexSchemaFromClassSchema(schema) ?? fail(\"leaf schema should be pre-cached\");\n\t\t\t\tassert(schemaIsLeaf(cached), 0x840 /* expected leaf */);\n\t\t\t\treturn cached;\n\t\t\t}\n\t\t\tcase NodeKind.Map: {\n\t\t\t\tconst fieldInfo = schema.info as ImplicitAllowedTypes;\n\t\t\t\tconst field = FlexFieldSchema.create(\n\t\t\t\t\tFieldKinds.optional,\n\t\t\t\t\tconvertAllowedTypes(schemaMap, fieldInfo),\n\t\t\t\t);\n\t\t\t\t// Lookup of cached schema is done here instead of before since walking the schema recursively to populate schemaMap is still required.\n\t\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\t\tout = cached ?? FlexMapNodeSchema.create(builder, brand(schema.identifier), field);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase NodeKind.Array: {\n\t\t\t\tconst fieldInfo = schema.info as ImplicitAllowedTypes;\n\t\t\t\tconst field = FlexFieldSchema.create(\n\t\t\t\t\tFieldKinds.sequence,\n\t\t\t\t\tconvertAllowedTypes(schemaMap, fieldInfo),\n\t\t\t\t);\n\t\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\t\tout = cached ?? FlexFieldNodeSchema.create(builder, brand(schema.identifier), field);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase NodeKind.Object: {\n\t\t\t\tconst info = schema.info as Record<string, ImplicitFieldSchema>;\n\t\t\t\tconst fields: Record<string, FlexFieldSchema> = Object.create(null);\n\t\t\t\tfor (const [viewKey, implicitFieldSchema] of Object.entries(info)) {\n\t\t\t\t\t// If a `stored key` was provided, use it as the key in the flex schema.\n\t\t\t\t\t// Otherwise, use the view key.\n\t\t\t\t\tconst flexKey = getStoredKey(viewKey, implicitFieldSchema);\n\n\t\t\t\t\t// This code has to be careful to avoid assigning to __proto__ or similar built-in fields.\n\t\t\t\t\tObject.defineProperty(fields, flexKey, {\n\t\t\t\t\t\tenumerable: true,\n\t\t\t\t\t\tconfigurable: false,\n\t\t\t\t\t\twritable: false,\n\t\t\t\t\t\tvalue: convertField(schemaMap, implicitFieldSchema),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\t\tout = cached ?? FlexObjectNodeSchema.create(builder, brand(schema.identifier), fields);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(kind);\n\t\t}\n\t\tassert(out instanceof TreeNodeSchemaBase, 0x841 /* invalid schema produced */);\n\t\t{\n\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tcachedFlexSchemaFromClassSchema(schema) === out,\n\t\t\t\t\t0x842 /* incorrect flexSchemaSymbol */,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsetFlexSchemaFromClassSchema(schema, out);\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t};\n\tschemaMap.set(brand(schema.identifier), { original: schema, toFlex });\n\treturn toFlex;\n}\n"]}
1
+ {"version":3,"file":"toFlexSchema.js","sourceRoot":"","sources":["../../src/simple-tree/toFlexSchema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAOtE,OAAO,EACN,UAAU,EAGV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EAIpB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,GACZ,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG7E,OAAO,EACN,+BAA+B,EAC/B,4BAA4B,EAC5B,sBAAsB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,SAAS,EACT,WAAW,EAIX,QAAQ,EAER,oBAAoB,EACpB,YAAY,GACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CACvC,MAA2B,EAC3B,IAAgD,EAChD,cAA8B,EAC9B,yBAAsD,SAAS;IAE/D,MAAM,IAAI,GAAG,IAAyB,CAAC;IACvC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,CACN,kBAAkB,CACjB,IAAI,EACJ,qBAAqB,CAAC,YAAY,EAClC,cAAc,EACd,sBAAsB,CACtB,IAAI,IAAI,CAAC,uBAAuB,CAAC,CAClC,CAAC;AACH,CAAC;AASD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAyB;IACrD,MAAM,SAAS,GAAc,IAAI,GAAG,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,GAAG,CACzB,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACP,MAAM,CACL,+BAA+B,CAAC,WAAW,CAAC,KAAK,MAAM,EACvD,KAAK,CAAC,uBAAuB,CAC7B,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtB,CAAC,CAAC,CACF,CAAC;IAEF,MAAM,KAAK,GAAmB;QAC7B,UAAU;QACV,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,mBAAmB;KAC3B,CAAC;IACF,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAoB;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,UAAU,CAAC,eAAe,CAAC,oBAAoB,IAAI,IAAI,CAAC,4BAA4B,CAAC,CAAC;AAC9F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC3B,SAAoB,EACpB,MAA2B;IAE3B,IAAI,IAAmB,CAAC;IACxB,IAAI,KAA2B,CAAC;IAChC,IAAI,MAAM,YAAY,WAAW,EAAE,CAAC;QACnC,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACvE,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;SAAM,CAAC;QACP,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC;QAC3B,KAAK,GAAG,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,YAAY,GAAG,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC3D,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAA2B;IAC1D,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC;IACzC,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC;IACzC,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC;CAC7C,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAClC,SAAoB,EACpB,MAA4B;IAE5B,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,CAAC,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAChC,SAAoB,EACpB,MAAsB;IAEtB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,4DAA4D;YAC5D,MAAM,IAAI,UAAU,CACnB,mDAAmD,IAAI,CAAC,SAAS,CAChE,MAAM,CAAC,UAAU,CACjB,iDAAiD,CAClD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,MAAM,GAAG,GAAuB,EAAE;QACvC,IAAI,GAAuB,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,QAAQ,IAAI,EAAE,CAAC;YACd,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACpB,MAAM,MAAM,GACX,+BAA+B,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,kCAAkC,CAAC,CAAC;gBACrF,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBACxD,OAAO,MAAM,CAAC;YACf,CAAC;YACD,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBACnB,MAAM,SAAS,GAAG,MAAM,CAAC,IAA4B,CAAC;gBACtD,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CACnC,UAAU,CAAC,QAAQ,EACnB,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CACzC,CAAC;gBACF,uIAAuI;gBACvI,MAAM,MAAM,GAAG,+BAA+B,CAAC,MAAM,CAAC,CAAC;gBACvD,GAAG,GAAG,MAAM,IAAI,iBAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;gBACnF,MAAM;YACP,CAAC;YACD,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrB,MAAM,SAAS,GAAG,MAAM,CAAC,IAA4B,CAAC;gBACtD,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CACnC,UAAU,CAAC,QAAQ,EACnB,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CACzC,CAAC;gBACF,MAAM,MAAM,GAAG,+BAA+B,CAAC,MAAM,CAAC,CAAC;gBACvD,GAAG,GAAG,MAAM,IAAI,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;gBACrF,MAAM;YACP,CAAC;YACD,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;gBACtB,MAAM,IAAI,GAAG,MAAM,CAAC,IAA2C,CAAC;gBAChE,MAAM,MAAM,GAAoC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACpE,KAAK,MAAM,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnE,wEAAwE;oBACxE,+BAA+B;oBAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;oBAE3D,0FAA0F;oBAC1F,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE;wBACtC,UAAU,EAAE,IAAI;wBAChB,YAAY,EAAE,KAAK;wBACnB,QAAQ,EAAE,KAAK;wBACf,KAAK,EAAE,YAAY,CAAC,SAAS,EAAE,mBAAmB,CAAC;qBACnD,CAAC,CAAC;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAG,+BAA+B,CAAC,MAAM,CAAC,CAAC;gBACvD,GAAG,GAAG,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;gBACvF,MAAM;YACP,CAAC;YACD;gBACC,eAAe,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,MAAM,CAAC,GAAG,YAAY,kBAAkB,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC/E,CAAC;YACA,MAAM,MAAM,GAAG,+BAA+B,CAAC,MAAM,CAAC,CAAC;YACvD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,CACL,+BAA+B,CAAC,MAAM,CAAC,KAAK,GAAG,EAC/C,KAAK,CAAC,gCAAgC,CACtC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,4BAA4B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC,CAAC;IACF,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtE,OAAO,MAAM,CAAC;AACf,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable import/no-internal-modules */\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type {\n\tITreeCursorSynchronous,\n\tTreeNodeSchemaIdentifier,\n\tSchemaAndPolicy,\n} from \"../core/index.js\";\nimport {\n\tFieldKinds,\n\ttype FlexAllowedTypes,\n\ttype FlexFieldKind,\n\tFlexFieldNodeSchema,\n\tFlexFieldSchema,\n\tFlexMapNodeSchema,\n\tFlexObjectNodeSchema,\n\ttype FlexTreeNodeSchema,\n\ttype FlexTreeSchema,\n\ttype NodeKeyManager,\n\tTreeNodeSchemaBase,\n\tdefaultSchemaPolicy,\n\tschemaIsLeaf,\n} from \"../feature-libraries/index.js\";\nimport { normalizeFlexListEager } from \"../feature-libraries/typed-schema/flexList.js\";\nimport { brand, fail, isReadonlyArray, mapIterable } from \"../util/index.js\";\n\nimport type { InsertableContent } from \"./proxies.js\";\nimport {\n\tcachedFlexSchemaFromClassSchema,\n\tsetFlexSchemaFromClassSchema,\n\ttryGetSimpleNodeSchema,\n} from \"./schemaCaching.js\";\nimport {\n\tFieldKind,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype ImplicitFieldSchema,\n\ttype InsertableTreeNodeFromImplicitAllowedTypes,\n\tNodeKind,\n\ttype TreeNodeSchema,\n\tnormalizeFieldSchema,\n\tgetStoredKey,\n} from \"./schemaTypes.js\";\nimport { cursorFromNodeData } from \"./toMapTree.js\";\n\n/**\n * Returns a cursor (in nodes mode) for the root node.\n *\n * @privateRemarks\n * Ideally this would work on any node, not just the root,\n * and the schema would come from the unhydrated node.\n * For now though, this is the only case that's needed, and we do have the data to make it work, so this is fine.\n */\nexport function cursorFromUnhydratedRoot(\n\tschema: ImplicitFieldSchema,\n\ttree: InsertableTreeNodeFromImplicitAllowedTypes,\n\tnodeKeyManager: NodeKeyManager,\n\tschemaValidationPolicy: SchemaAndPolicy | undefined = undefined,\n): ITreeCursorSynchronous {\n\tconst data = tree as InsertableContent;\n\tconst normalizedFieldSchema = normalizeFieldSchema(schema);\n\treturn (\n\t\tcursorFromNodeData(\n\t\t\tdata,\n\t\t\tnormalizedFieldSchema.allowedTypes,\n\t\t\tnodeKeyManager,\n\t\t\tschemaValidationPolicy,\n\t\t) ?? fail(\"failed to decode tree\")\n\t);\n}\n\ninterface SchemaInfo {\n\treadonly toFlex: () => FlexTreeNodeSchema;\n\treadonly original: TreeNodeSchema;\n}\n\ntype SchemaMap = Map<TreeNodeSchemaIdentifier, SchemaInfo>;\n\n/**\n * Generate a {@link FlexTreeSchema} with `root` as the root field.\n *\n * This also has the side effect of populating the cached view schema on the class-based schema.\n */\nexport function toFlexSchema(root: ImplicitFieldSchema): FlexTreeSchema {\n\tconst schemaMap: SchemaMap = new Map();\n\tconst field = convertField(schemaMap, root);\n\tconst nodeSchema = new Map(\n\t\tmapIterable(schemaMap, ([key, value]) => {\n\t\t\tconst schema = value.toFlex();\n\t\t\tconst classSchema = tryGetSimpleNodeSchema(schema);\n\t\t\tif (classSchema === undefined) {\n\t\t\t\tassert(schemaIsLeaf(schema), 0x83e /* invalid leaf */);\n\t\t\t} else {\n\t\t\t\tassert(\n\t\t\t\t\tcachedFlexSchemaFromClassSchema(classSchema) === schema,\n\t\t\t\t\t0x83f /* mismatched schema */,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn [key, schema];\n\t\t}),\n\t);\n\n\tconst typed: FlexTreeSchema = {\n\t\tnodeSchema,\n\t\tadapters: {},\n\t\trootFieldSchema: field,\n\t\tpolicy: defaultSchemaPolicy,\n\t};\n\treturn typed;\n}\n\n/**\n * Return a flex schema for the provided class schema.\n *\n * This also has the side effect of populating the cached view schema on the class based schema.\n */\nexport function getFlexSchema(root: TreeNodeSchema): FlexTreeNodeSchema {\n\tconst treeSchema = toFlexSchema(root);\n\treturn treeSchema.rootFieldSchema.monomorphicChildType ?? fail(\"root should be monomorphic\");\n}\n\n/**\n * Normalizes an {@link ImplicitFieldSchema} into a {@link TreeFieldSchema}.\n */\nexport function convertField(\n\tschemaMap: SchemaMap,\n\tschema: ImplicitFieldSchema,\n): FlexFieldSchema {\n\tlet kind: FlexFieldKind;\n\tlet types: ImplicitAllowedTypes;\n\tif (schema instanceof FieldSchema) {\n\t\tkind = convertFieldKind.get(schema.kind) ?? fail(\"Invalid field kind\");\n\t\ttypes = schema.allowedTypes;\n\t} else {\n\t\tkind = FieldKinds.required;\n\t\ttypes = schema;\n\t}\n\tconst allowedTypes = convertAllowedTypes(schemaMap, types);\n\treturn FlexFieldSchema.create(kind, allowedTypes);\n}\n\nconst convertFieldKind = new Map<FieldKind, FlexFieldKind>([\n\t[FieldKind.Optional, FieldKinds.optional],\n\t[FieldKind.Required, FieldKinds.required],\n\t[FieldKind.Identifier, FieldKinds.identifier],\n]);\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} into an {@link AllowedTypes}.\n */\nexport function convertAllowedTypes(\n\tschemaMap: SchemaMap,\n\tschema: ImplicitAllowedTypes,\n): FlexAllowedTypes {\n\tif (isReadonlyArray(schema)) {\n\t\treturn normalizeFlexListEager(schema).map((item) => convertNodeSchema(schemaMap, item));\n\t}\n\treturn [convertNodeSchema(schemaMap, schema)];\n}\n\nconst builder = { name: \"simple schema\" };\n\n/**\n * Converts a {@link TreeNodeSchema} into a {@link FlexTreeNodeSchema}.\n * Ensures all types reachable from `schema` are included in `schemaMap`.\n *\n * Return value (and entries in map) are lazy to allow recursive types to work.\n * This laziness does NOT extend to adding entries to `schemaMap`:\n * all referenced types are added to it before this function returns.\n */\nexport function convertNodeSchema(\n\tschemaMap: SchemaMap,\n\tschema: TreeNodeSchema,\n): () => FlexTreeNodeSchema {\n\tconst fromMap = schemaMap.get(brand(schema.identifier));\n\tif (fromMap !== undefined) {\n\t\tif (fromMap.original !== schema) {\n\t\t\t// Use JSON.stringify to quote and escape identifier string.\n\t\t\tthrow new UsageError(\n\t\t\t\t`Multiple schema encountered with the identifier ${JSON.stringify(\n\t\t\t\t\tschema.identifier,\n\t\t\t\t)}. Remove or rename them to avoid the collision.`,\n\t\t\t);\n\t\t}\n\t\treturn fromMap.toFlex;\n\t}\n\n\tconst toFlex = (): FlexTreeNodeSchema => {\n\t\tlet out: FlexTreeNodeSchema;\n\t\tconst kind = schema.kind;\n\t\tswitch (kind) {\n\t\t\tcase NodeKind.Leaf: {\n\t\t\t\tconst cached =\n\t\t\t\t\tcachedFlexSchemaFromClassSchema(schema) ?? fail(\"leaf schema should be pre-cached\");\n\t\t\t\tassert(schemaIsLeaf(cached), 0x840 /* expected leaf */);\n\t\t\t\treturn cached;\n\t\t\t}\n\t\t\tcase NodeKind.Map: {\n\t\t\t\tconst fieldInfo = schema.info as ImplicitAllowedTypes;\n\t\t\t\tconst field = FlexFieldSchema.create(\n\t\t\t\t\tFieldKinds.optional,\n\t\t\t\t\tconvertAllowedTypes(schemaMap, fieldInfo),\n\t\t\t\t);\n\t\t\t\t// Lookup of cached schema is done here instead of before since walking the schema recursively to populate schemaMap is still required.\n\t\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\t\tout = cached ?? FlexMapNodeSchema.create(builder, brand(schema.identifier), field);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase NodeKind.Array: {\n\t\t\t\tconst fieldInfo = schema.info as ImplicitAllowedTypes;\n\t\t\t\tconst field = FlexFieldSchema.create(\n\t\t\t\t\tFieldKinds.sequence,\n\t\t\t\t\tconvertAllowedTypes(schemaMap, fieldInfo),\n\t\t\t\t);\n\t\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\t\tout = cached ?? FlexFieldNodeSchema.create(builder, brand(schema.identifier), field);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase NodeKind.Object: {\n\t\t\t\tconst info = schema.info as Record<string, ImplicitFieldSchema>;\n\t\t\t\tconst fields: Record<string, FlexFieldSchema> = Object.create(null);\n\t\t\t\tfor (const [viewKey, implicitFieldSchema] of Object.entries(info)) {\n\t\t\t\t\t// If a `stored key` was provided, use it as the key in the flex schema.\n\t\t\t\t\t// Otherwise, use the view key.\n\t\t\t\t\tconst flexKey = getStoredKey(viewKey, implicitFieldSchema);\n\n\t\t\t\t\t// This code has to be careful to avoid assigning to __proto__ or similar built-in fields.\n\t\t\t\t\tObject.defineProperty(fields, flexKey, {\n\t\t\t\t\t\tenumerable: true,\n\t\t\t\t\t\tconfigurable: false,\n\t\t\t\t\t\twritable: false,\n\t\t\t\t\t\tvalue: convertField(schemaMap, implicitFieldSchema),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\t\tout = cached ?? FlexObjectNodeSchema.create(builder, brand(schema.identifier), fields);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(kind);\n\t\t}\n\t\tassert(out instanceof TreeNodeSchemaBase, 0x841 /* invalid schema produced */);\n\t\t{\n\t\t\tconst cached = cachedFlexSchemaFromClassSchema(schema);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tcachedFlexSchemaFromClassSchema(schema) === out,\n\t\t\t\t\t0x842 /* incorrect flexSchemaSymbol */,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsetFlexSchemaFromClassSchema(schema, out);\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t};\n\tschemaMap.set(brand(schema.identifier), { original: schema, toFlex });\n\treturn toFlex;\n}\n"]}
@@ -6,7 +6,7 @@ import type { IFluidLoadable, IDisposable } from "@fluidframework/core-interface
6
6
  import type { CommitMetadata } from "../core/index.js";
7
7
  import type { Listenable } from "../events/index.js";
8
8
  import type { RevertibleFactory } from "../shared-tree/index.js";
9
- import type { ImplicitFieldSchema, InsertableTreeFieldFromImplicitField, TreeFieldFromImplicitField } from "./schemaTypes.js";
9
+ import { type ImplicitFieldSchema, type InsertableTreeFieldFromImplicitField, type TreeFieldFromImplicitField, type TreeNodeSchema } from "./schemaTypes.js";
10
10
  /**
11
11
  * Channel for a Fluid Tree DDS.
12
12
  * @remarks
@@ -104,6 +104,9 @@ export declare class TreeViewConfiguration<TSchema extends ImplicitFieldSchema =
104
104
  */
105
105
  constructor(props: ITreeViewConfiguration<TSchema>);
106
106
  }
107
+ export declare function walkNodeSchema(schema: TreeNodeSchema, visitor: (schema: TreeNodeSchema) => void, visitedSet: Set<TreeNodeSchema>): void;
108
+ export declare function walkFieldSchema(schema: ImplicitFieldSchema, visitor: (schema: TreeNodeSchema) => void, visitedSet?: Set<TreeNodeSchema>): void;
109
+ export declare function walkAllowedTypes(allowedTypes: Iterable<TreeNodeSchema>, visitor: (schema: TreeNodeSchema) => void, visitedSet: Set<TreeNodeSchema>): void;
107
110
  /**
108
111
  * An editable view of a (version control style) branch of a shared tree based on some schema.
109
112
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EACX,mBAAmB,EACnB,oCAAoC,EACpC,0BAA0B,EAC1B,MAAM,kBAAkB,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,WAAW,KAAM,SAAQ,cAAc;IAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,QAAQ,CAAC,KAAK,SAAS,mBAAmB,EACzC,MAAM,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAClC,QAAQ,CAAC,KAAK,CAAC,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACjC;AAMD;;;GAGG;AACH,MAAM,WAAW,sBAAsB,CACtC,OAAO,SAAS,mBAAmB,GAAG,mBAAmB;IAEzD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED;;;GAGG;AACH,qBAAa,qBAAqB,CAAC,OAAO,SAAS,mBAAmB,GAAG,mBAAmB,CAC3F,YAAW,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEpD;;OAEG;IACH,SAAgB,MAAM,EAAE,OAAO,CAAC;IAEhC;;OAEG;IACH,SAAgB,sBAAsB,EAAE,OAAO,CAAC;IAEhD;;OAEG;gBACgB,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC;CAKzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,mBAAmB,CAAE,SAAQ,WAAW;IACjF;;;;;;;;;;;OAWG;IACH,IAAI,IAAI,IAAI,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,IAAI,CAAC,OAAO,EAAE,oCAAoC,CAAC,OAAO,CAAC,EAAE;IAEjE;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,yBAAyB,CAAC;IAElD;;;;;;;;;;;;;OAaG;IACH,aAAa,IAAI,IAAI,CAAC;IAEtB;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,oCAAoC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAEzE;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAE7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CAKhC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,WAAW,IAAI,IAAI,CAAC;IAEpB;;;;;;;OAOG;IACH,aAAa,IAAI,IAAI,CAAC;IAEtB;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,aAAa,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC7E"}
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAIN,KAAK,mBAAmB,EACxB,KAAK,oCAAoC,EACzC,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,MAAM,kBAAkB,CAAC;AAO1B;;;;;GAKG;AACH,MAAM,WAAW,KAAM,SAAQ,cAAc;IAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,QAAQ,CAAC,KAAK,SAAS,mBAAmB,EACzC,MAAM,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAClC,QAAQ,CAAC,KAAK,CAAC,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACjC;AAMD;;;GAGG;AACH,MAAM,WAAW,sBAAsB,CACtC,OAAO,SAAS,mBAAmB,GAAG,mBAAmB;IAEzD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED;;;GAGG;AACH,qBAAa,qBAAqB,CAAC,OAAO,SAAS,mBAAmB,GAAG,mBAAmB,CAC3F,YAAW,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEpD;;OAEG;IACH,SAAgB,MAAM,EAAE,OAAO,CAAC;IAEhC;;OAEG;IACH,SAAgB,sBAAsB,EAAE,OAAO,CAAC;IAEhD;;OAEG;gBACgB,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC;CAYzD;AAED,wBAAgB,cAAc,CAC7B,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,EACzC,UAAU,EAAE,GAAG,CAAC,cAAc,CAAC,GAC7B,IAAI,CAwBN;AAED,wBAAgB,eAAe,CAC9B,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,EACzC,UAAU,GAAE,GAAG,CAAC,cAAc,CAAa,GACzC,IAAI,CAEN;AAED,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,QAAQ,CAAC,cAAc,CAAC,EACtC,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,EACzC,UAAU,EAAE,GAAG,CAAC,cAAc,CAAC,GAC7B,IAAI,CAIN;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,mBAAmB,CAAE,SAAQ,WAAW;IACjF;;;;;;;;;;;OAWG;IACH,IAAI,IAAI,IAAI,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,IAAI,CAAC,OAAO,EAAE,oCAAoC,CAAC,OAAO,CAAC,EAAE;IAEjE;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,yBAAyB,CAAC;IAElD;;;;;;;;;;;;;OAaG;IACH,aAAa,IAAI,IAAI,CAAC;IAEtB;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,oCAAoC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAEzE;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAE7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CAKhC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,WAAW,IAAI,IAAI,CAAC;IAEpB;;;;;;;OAOG;IACH,aAAa,IAAI,IAAI,CAAC;IAEtB;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,aAAa,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC7E"}
@@ -2,6 +2,12 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import { NodeKind, normalizeFieldSchema, } from "./schemaTypes.js";
6
+ import { toFlexSchema } from "./toFlexSchema.js";
7
+ import { LeafNodeSchema } from "./leafNodeSchema.js";
8
+ import { assert } from "@fluidframework/core-utils/internal";
9
+ import { isObjectNodeSchema } from "./objectNode.js";
10
+ import { markSchemaMostDerived } from "./schemaFactory.js";
5
11
  const defaultTreeConfigurationOptions = {
6
12
  enableSchemaValidation: false,
7
13
  };
@@ -17,6 +23,44 @@ export class TreeViewConfiguration {
17
23
  const config = { ...defaultTreeConfigurationOptions, ...props };
18
24
  this.schema = config.schema;
19
25
  this.enableSchemaValidation = config.enableSchemaValidation;
26
+ // Ensure all reachable schema are marked as most derived.
27
+ // This ensures if multiple schema extending the same schema factory generated class are present (or have been constructed, or get constructed in the future),
28
+ // an error is reported.
29
+ walkFieldSchema(config.schema, markSchemaMostDerived);
30
+ // Eagerly perform this conversion to surface errors sooner.
31
+ toFlexSchema(config.schema);
32
+ }
33
+ }
34
+ export function walkNodeSchema(schema, visitor, visitedSet) {
35
+ if (visitedSet.has(schema)) {
36
+ return;
37
+ }
38
+ visitedSet.add(schema);
39
+ if (schema instanceof LeafNodeSchema) {
40
+ // nothing to do
41
+ }
42
+ else if (isObjectNodeSchema(schema)) {
43
+ for (const field of schema.fields.values()) {
44
+ walkAllowedTypes(field.allowedTypeSet, visitor, visitedSet);
45
+ }
46
+ }
47
+ else {
48
+ assert(schema.kind === NodeKind.Array || schema.kind === NodeKind.Map, 0x9b3 /* invalid schema */);
49
+ const childTypes = schema.info;
50
+ walkFieldSchema(childTypes, visitor, visitedSet);
51
+ }
52
+ // This visit is done at the end so the traversal order is most inner types first.
53
+ // This was picked since when fixing errors,
54
+ // working from the inner types out to the types that use them will probably go better than the reverse.
55
+ // This does not however ensure all types referenced by a type are visited before it, since in recursive cases thats impossible.
56
+ visitor(schema);
57
+ }
58
+ export function walkFieldSchema(schema, visitor, visitedSet = new Set()) {
59
+ walkAllowedTypes(normalizeFieldSchema(schema).allowedTypeSet, visitor, visitedSet);
60
+ }
61
+ export function walkAllowedTypes(allowedTypes, visitor, visitedSet) {
62
+ for (const childType of allowedTypes) {
63
+ walkNodeSchema(childType, visitor, visitedSet);
20
64
  }
21
65
  }
22
66
  //# sourceMappingURL=tree.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4EH,MAAM,+BAA+B,GAAwC;IAC5E,sBAAsB,EAAE,KAAK;CAC7B,CAAC;AA2BF;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAajC;;OAEG;IACH,YAAmB,KAAsC;QACxD,MAAM,MAAM,GAAG,EAAE,GAAG,+BAA+B,EAAE,GAAG,KAAK,EAAE,CAAC;QAChE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,sBAAsB,CAAC;IAC7D,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IFluidLoadable, IDisposable } from \"@fluidframework/core-interfaces\";\n\nimport type { CommitMetadata } from \"../core/index.js\";\nimport type { Listenable } from \"../events/index.js\";\nimport type { RevertibleFactory } from \"../shared-tree/index.js\";\n\nimport type {\n\tImplicitFieldSchema,\n\tInsertableTreeFieldFromImplicitField,\n\tTreeFieldFromImplicitField,\n} from \"./schemaTypes.js\";\n\n/**\n * Channel for a Fluid Tree DDS.\n * @remarks\n * Allows storing and collaboratively editing schema-aware hierarchial data.\n * @sealed @public\n */\nexport interface ITree extends IFluidLoadable {\n\t/**\n\t * Returns a {@link TreeView} using the provided schema.\n\t * If the stored schema is compatible with the view schema specified by `config`,\n\t * the returned {@link TreeView} will expose the root with a schema-aware API based on the provided view schema.\n\t * If the provided schema is incompatible with the stored schema, the view will instead expose a status indicating the incompatibility.\n\t *\n\t * @remarks\n\t * If the tree is uninitialized (has no schema and no content), use {@link TreeView.initialize} on the returned view to set the schema and content together.\n\t * Using `viewWith` followed by {@link TreeView.upgradeSchema} to initialize only the schema for a document is technically valid when the schema\n\t * permits trees with no content.\n\t *\n\t * 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.\n\t *\n\t * Only one schematized view may exist for a given ITree at a time.\n\t * If creating a second, the first must be disposed before calling `viewWith` again.\n\t *\n\t * @privateRemarks\n\t * TODO: Provide a way to make a generic view schema for any document.\n\t * TODO: Support adapters for handling out-of-schema data.\n\t *\n\t * Doing initialization here allows a small API that is hard to use incorrectly.\n\t * Other approaches tend to have easy-to-make mistakes.\n\t * For example, having a separate initialization function means apps can forget to call it, making an app that can only open existing documents,\n\t * or call it unconditionally leaving an app that can only create new documents.\n\t * It also would require the schema to be passed into separate places and could cause issues if they didn't match.\n\t * Since the initialization function couldn't return a typed tree, the type checking wouldn't help catch that.\n\t * Also, if an app manages to create a document, but the initialization fails to get persisted, an app that only calls the initialization function\n\t * on the create code-path (for example how a schematized factory might do it),\n\t * would leave the document in an unusable state which could not be repaired when it is reopened (by the same or other clients).\n\t * Additionally, once out of schema content adapters are properly supported (with lazy document updates),\n\t * this initialization could become just another out of schema content adapter and this initialization is no longer a special case.\n\t */\n\tviewWith<TRoot extends ImplicitFieldSchema>(\n\t\tconfig: TreeViewConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * Options when constructing a tree view.\n * @public\n */\nexport interface ITreeConfigurationOptions {\n\t/**\n\t * If `true`, the tree will validate new content against its stored schema at insertion time\n\t * and throw an error if the new content doesn't match the expected schema.\n\t *\n\t * @defaultValue `false`.\n\t *\n\t * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because\n\t * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a\n\t * bit slower.\n\t */\n\tenableSchemaValidation?: boolean;\n}\n\nconst defaultTreeConfigurationOptions: Required<ITreeConfigurationOptions> = {\n\tenableSchemaValidation: false,\n};\n\n/**\n * Property-bag configuration for {@link TreeViewConfiguration} construction.\n * @public\n */\nexport interface ITreeViewConfiguration<\n\tTSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n> {\n\t/**\n\t * The schema which the application wants to view the tree with.\n\t */\n\treadonly schema: TSchema;\n\n\t/**\n\t * If `true`, the tree will validate new content against its stored schema at insertion time\n\t * and throw an error if the new content doesn't match the expected schema.\n\t *\n\t * @defaultValue `false`.\n\t *\n\t * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because\n\t * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a\n\t * bit slower.\n\t */\n\treadonly enableSchemaValidation?: boolean;\n}\n\n/**\n * Configuration for {@link ITree.viewWith}.\n * @sealed @public\n */\nexport class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema>\n\timplements Required<ITreeViewConfiguration<TSchema>>\n{\n\t/**\n\t * {@inheritDoc ITreeViewConfiguration.schema}\n\t */\n\tpublic readonly schema: TSchema;\n\n\t/**\n\t * {@inheritDoc ITreeViewConfiguration.enableSchemaValidation}\n\t */\n\tpublic readonly enableSchemaValidation: boolean;\n\n\t/**\n\t * @param props - Property bag of configuration options.\n\t */\n\tpublic constructor(props: ITreeViewConfiguration<TSchema>) {\n\t\tconst config = { ...defaultTreeConfigurationOptions, ...props };\n\t\tthis.schema = config.schema;\n\t\tthis.enableSchemaValidation = config.enableSchemaValidation;\n\t}\n}\n\n/**\n * An editable view of a (version control style) branch of a shared tree based on some schema.\n *\n * This schema--known as the view schema--may or may not align the stored schema of the document.\n * Information about discrepancies between the two schemas is available via {@link TreeView.compatibility | compatibility}.\n *\n * Application authors are encouraged to read [schema-evolution.md](../../docs/user-facing/schema-evolution.md) and\n * choose a schema compatibility policy that aligns with their application's needs.\n *\n * @privateRemarks\n * From an API design perspective, `upgradeSchema` could be merged into `viewWith` and/or `viewWith` could return errors explicitly on incompatible documents.\n * Such approaches would make it discoverable that out of schema handling may need to be done.\n * Doing that would however complicate trivial \"hello world\" style example slightly, as well as be a breaking API change.\n * It also seems more complex to handle invalidation with that pattern.\n * Thus this design was chosen at the risk of apps blindly accessing `root` then breaking unexpectedly when the document is incompatible.\n * @sealed @public\n */\nexport interface TreeView<TSchema extends ImplicitFieldSchema> extends IDisposable {\n\t/**\n\t * The current root of the tree.\n\t *\n\t * If the view schema not sufficiently compatible with the stored schema, accessing this will throw.\n\t * To handle this case, check {@link TreeView.compatibility | compatibility}'s {@link SchemaCompatibilityStatus.canView | canView} before using.\n\t *\n\t * To get notified about changes to this field,\n\t * use {@link TreeViewEvents.rootChanged} via `view.events.on(\"rootChanged\", callback)`.\n\t *\n\t * To get notified about changes to stored schema (which may affect compatibility between this view's schema and\n\t * the stored schema), use {@link TreeViewEvents.schemaChanged} via `view.events.on(\"schemaChanged\", callback)`.\n\t */\n\tget root(): TreeFieldFromImplicitField<TSchema>;\n\n\tset root(newRoot: InsertableTreeFieldFromImplicitField<TSchema>);\n\n\t/**\n\t * Description of the current compatibility status between the view schema and stored schema.\n\t *\n\t * {@link TreeViewEvents.schemaChanged} is fired when the compatibility status changes.\n\t */\n\treadonly compatibility: SchemaCompatibilityStatus;\n\n\t/**\n\t * When the schemas are not an exact match and {@link SchemaCompatibilityStatus.canUpgrade} is true,\n\t * this can be used to modify the stored schema to make it match the view schema.\n\t * This will update the compatibility state, and allow access to `root`.\n\t * Beware that this may impact other clients' ability to view the document depending on the application's schema compatibility policy!\n\t * @remarks\n\t * It is an error to call this when {@link SchemaCompatibilityStatus.canUpgrade} is false, and a no-op when the stored and view schema are already an exact match.\n\t * @privateRemarks\n\t * In the future, more upgrade options could be provided here.\n\t * Some options that could be added:\n\t * - check the actual document contents (not just the schema) and attempt an atomic document update if the data is compatible.\n\t * - apply converters and upgrade the document.\n\t * - apply converters to lazily to adapt the document to the requested view schema (with optional lazy schema updates or transparent conversions on write).\n\t */\n\tupgradeSchema(): void;\n\n\t/**\n\t * Initialize the tree, setting the stored schema to match this view's schema and setting the tree content.\n\t *\n\t * Only valid to call when this view's {@link SchemaCompatibilityStatus.canInitialize} is true.\n\t *\n\t * Applications should typically call this function before attaching a `SharedTree`.\n\t * @param content - The content to initialize the tree with.\n\t */\n\tinitialize(content: InsertableTreeFieldFromImplicitField<TSchema>): void;\n\n\t/**\n\t * Events for the tree.\n\t */\n\treadonly events: Listenable<TreeViewEvents>;\n}\n\n/**\n * Information about a view schema's compatibility with the document's stored schema.\n *\n * See SharedTree's README for more information about choosing a compatibility policy.\n * @sealed @public\n */\nexport interface SchemaCompatibilityStatus {\n\t/**\n\t * Whether the view schema allows exactly the same set of documents as the stored schema.\n\t *\n\t * @remarks\n\t * Equivalence here is defined in terms of allowed documents because there are some degenerate cases where schemas are not\n\t * exact matches in a strict (schema-based) sense but still allow the same documents, and the document notion is more useful to applications.\n\t *\n\t * Examples which are expressible where this may occur include:\n\t * - schema repository `A` has extra schema which schema `B` doesn't have, but they are unused (i.e. not reachable from the root schema)\n\t * - field in schema `A` has allowed field members which the corresponding field in schema `B` does not have, but those types are not constructible (ex: an object node type containing a required field with no allowed types)\n\t *\n\t * These cases are typically not interesting to applications.\n\t */\n\treadonly isEquivalent: boolean;\n\n\t/**\n\t * Whether the current view schema is sufficiently compatible with the stored schema to allow viewing tree data.\n\t * If false, {@link TreeView.root} will throw upon access.\n\t *\n\t * Currently, this field is true iff `isEquivalent` is true.\n\t * Do not rely on this:\n\t * there are near-term plans to extend support for viewing documents when the stored schema contains additional optional fields not present in the view schema.\n\t * The other two types of backward-compatible changes (field relaxations and addition of allowed field types) will eventually be supported as well,\n\t * likely through out-of-schema content adapters that the application can provide alongside their view schema.\n\t *\n\t * Be aware that even with these SharedTree limitations fixed, application logic may not correctly tolerate the documents allowable by the stored schema!\n\t * Application authors are encouraged to read docs/user-facing/schema-evolution.md and choose a schema compatibility policy that\n\t * aligns with their application's needs.\n\t *\n\t * @remarks\n\t * When the documents allowed by the view schema is a strict superset of those by the stored schema,\n\t * this is false because writes to the document using the view schema could make the document violate its stored schema.\n\t * In this case, the stored schema could be updated to match the provided view schema, allowing read-write access to the tree.\n\t * See {@link SchemaCompatibilityStatus.canUpgrade}.\n\t *\n\t * Future version of SharedTree may provide readonly access to the document in this case because that would be safe,\n\t * but this is not currently supported.\n\t *\n\t * @privateRemarks\n\t * A necessary condition for this to be true is that the documents allowed by the view schema are a subset of those allowed by the stored schema.\n\t * This is not sufficient: the simple-tree layer's read APIs do not tolerate out-of-schema data.\n\t * For example, if the view schema for a node has a required `Point` field but the stored schema has an optional `Point` field,\n\t * read APIs on the view schema do not work correctly when the document has a node with a missing `Point` field.\n\t * Similar issues happen when the view schema has a field with less allowed types than the stored schema and the document actually leverages those types.\n\t */\n\treadonly canView: boolean;\n\n\t/**\n\t * True iff the view schema supports all possible documents permitted by the stored schema.\n\t * When true, it is valid to call {@link TreeView.upgradeSchema} (though if the stored schema is already an exact match, this is a no-op).\n\t */\n\treadonly canUpgrade: boolean;\n\n\t/**\n\t * True iff the document is uninitialized (i.e. it has no schema and no content).\n\t *\n\t * To initialize the document, call {@link TreeView.initialize}.\n\t *\n\t * @remarks\n\t * It's not necessary to check this field before calling {@link TreeView.initialize} in most scenarios; application authors typically know from\n\t * context that they're in a flow which creates a new `SharedTree` and would like to initialize it.\n\t */\n\treadonly canInitialize: boolean;\n\n\t// TODO: Consider extending this status to include:\n\t// - application-defined metadata about the stored schema\n\t// - details about the differences between the stored and view schema sufficient for implementing \"safe mismatch\" policies\n}\n\n/**\n * Events for {@link TreeView}.\n * @sealed @public\n */\nexport interface TreeViewEvents {\n\t/**\n\t * Raised whenever {@link TreeView.root} is invalidated.\n\t *\n\t * This includes changes to the document schema.\n\t * It also includes changes to the field containing the root such as setting or clearing an optional root or changing which node is the root.\n\t * This does NOT include changes to the content (fields/children) of the root node: for that case subscribe to events on the root node.\n\t */\n\trootChanged(): void;\n\n\t/**\n\t * The stored schema for the document has changed.\n\t * This may affect the compatibility between the view schema and the stored schema, and thus the ability to use the view.\n\t *\n\t * @remarks\n\t * This event implies that the old {@link TreeView.root} is no longer valid, but applications need not handle that separately:\n\t * {@link TreeViewEvents.rootChanged} will be fired after this event.\n\t */\n\tschemaChanged(): void;\n\n\t/**\n\t * Fired when:\n\t * - a local commit is applied outside of a transaction\n\t * - a local transaction is committed\n\t *\n\t * The event is not fired when:\n\t * - a local commit is applied within a transaction\n\t * - a remote commit is applied\n\t *\n\t * @param data - information about the commit that was applied\n\t * @param getRevertible - a function provided that allows users to get a revertible for the commit that was applied. If not provided,\n\t * this commit is not revertible.\n\t */\n\tcommitApplied(data: CommitMetadata, getRevertible?: RevertibleFactory): void;\n}\n"]}
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAEN,QAAQ,EACR,oBAAoB,GAKpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAgE3D,MAAM,+BAA+B,GAAwC;IAC5E,sBAAsB,EAAE,KAAK;CAC7B,CAAC;AA2BF;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAajC;;OAEG;IACH,YAAmB,KAAsC;QACxD,MAAM,MAAM,GAAG,EAAE,GAAG,+BAA+B,EAAE,GAAG,KAAK,EAAE,CAAC;QAChE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,sBAAsB,CAAC;QAE5D,0DAA0D;QAC1D,8JAA8J;QAC9J,wBAAwB;QACxB,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;QACtD,4DAA4D;QAC5D,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;CACD;AAED,MAAM,UAAU,cAAc,CAC7B,MAAsB,EACtB,OAAyC,EACzC,UAA+B;IAE/B,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,OAAO;IACR,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,IAAI,MAAM,YAAY,cAAc,EAAE,CAAC;QACtC,gBAAgB;IACjB,CAAC;SAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,gBAAgB,CAAC,KAAK,CAAC,cAAc,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;SAAM,CAAC;QACP,MAAM,CACL,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,GAAG,EAC9D,KAAK,CAAC,oBAAoB,CAC1B,CAAC;QACF,MAAM,UAAU,GAAG,MAAM,CAAC,IAA4B,CAAC;QACvD,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;IACD,kFAAkF;IAClF,4CAA4C;IAC5C,wGAAwG;IACxG,gIAAgI;IAChI,OAAO,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAC9B,MAA2B,EAC3B,OAAyC,EACzC,aAAkC,IAAI,GAAG,EAAE;IAE3C,gBAAgB,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC/B,YAAsC,EACtC,OAAyC,EACzC,UAA+B;IAE/B,KAAK,MAAM,SAAS,IAAI,YAAY,EAAE,CAAC;QACtC,cAAc,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAChD,CAAC;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IFluidLoadable, IDisposable } from \"@fluidframework/core-interfaces\";\n\nimport type { CommitMetadata } from \"../core/index.js\";\nimport type { Listenable } from \"../events/index.js\";\nimport type { RevertibleFactory } from \"../shared-tree/index.js\";\n\nimport {\n\ttype ImplicitAllowedTypes,\n\tNodeKind,\n\tnormalizeFieldSchema,\n\ttype ImplicitFieldSchema,\n\ttype InsertableTreeFieldFromImplicitField,\n\ttype TreeFieldFromImplicitField,\n\ttype TreeNodeSchema,\n} from \"./schemaTypes.js\";\nimport { toFlexSchema } from \"./toFlexSchema.js\";\nimport { LeafNodeSchema } from \"./leafNodeSchema.js\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { isObjectNodeSchema } from \"./objectNode.js\";\nimport { markSchemaMostDerived } from \"./schemaFactory.js\";\n\n/**\n * Channel for a Fluid Tree DDS.\n * @remarks\n * Allows storing and collaboratively editing schema-aware hierarchial data.\n * @sealed @public\n */\nexport interface ITree extends IFluidLoadable {\n\t/**\n\t * Returns a {@link TreeView} using the provided schema.\n\t * If the stored schema is compatible with the view schema specified by `config`,\n\t * the returned {@link TreeView} will expose the root with a schema-aware API based on the provided view schema.\n\t * If the provided schema is incompatible with the stored schema, the view will instead expose a status indicating the incompatibility.\n\t *\n\t * @remarks\n\t * If the tree is uninitialized (has no schema and no content), use {@link TreeView.initialize} on the returned view to set the schema and content together.\n\t * Using `viewWith` followed by {@link TreeView.upgradeSchema} to initialize only the schema for a document is technically valid when the schema\n\t * permits trees with no content.\n\t *\n\t * 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.\n\t *\n\t * Only one schematized view may exist for a given ITree at a time.\n\t * If creating a second, the first must be disposed before calling `viewWith` again.\n\t *\n\t * @privateRemarks\n\t * TODO: Provide a way to make a generic view schema for any document.\n\t * TODO: Support adapters for handling out-of-schema data.\n\t *\n\t * Doing initialization here allows a small API that is hard to use incorrectly.\n\t * Other approaches tend to have easy-to-make mistakes.\n\t * For example, having a separate initialization function means apps can forget to call it, making an app that can only open existing documents,\n\t * or call it unconditionally leaving an app that can only create new documents.\n\t * It also would require the schema to be passed into separate places and could cause issues if they didn't match.\n\t * Since the initialization function couldn't return a typed tree, the type checking wouldn't help catch that.\n\t * Also, if an app manages to create a document, but the initialization fails to get persisted, an app that only calls the initialization function\n\t * on the create code-path (for example how a schematized factory might do it),\n\t * would leave the document in an unusable state which could not be repaired when it is reopened (by the same or other clients).\n\t * Additionally, once out of schema content adapters are properly supported (with lazy document updates),\n\t * this initialization could become just another out of schema content adapter and this initialization is no longer a special case.\n\t */\n\tviewWith<TRoot extends ImplicitFieldSchema>(\n\t\tconfig: TreeViewConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * Options when constructing a tree view.\n * @public\n */\nexport interface ITreeConfigurationOptions {\n\t/**\n\t * If `true`, the tree will validate new content against its stored schema at insertion time\n\t * and throw an error if the new content doesn't match the expected schema.\n\t *\n\t * @defaultValue `false`.\n\t *\n\t * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because\n\t * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a\n\t * bit slower.\n\t */\n\tenableSchemaValidation?: boolean;\n}\n\nconst defaultTreeConfigurationOptions: Required<ITreeConfigurationOptions> = {\n\tenableSchemaValidation: false,\n};\n\n/**\n * Property-bag configuration for {@link TreeViewConfiguration} construction.\n * @public\n */\nexport interface ITreeViewConfiguration<\n\tTSchema extends ImplicitFieldSchema = ImplicitFieldSchema,\n> {\n\t/**\n\t * The schema which the application wants to view the tree with.\n\t */\n\treadonly schema: TSchema;\n\n\t/**\n\t * If `true`, the tree will validate new content against its stored schema at insertion time\n\t * and throw an error if the new content doesn't match the expected schema.\n\t *\n\t * @defaultValue `false`.\n\t *\n\t * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because\n\t * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a\n\t * bit slower.\n\t */\n\treadonly enableSchemaValidation?: boolean;\n}\n\n/**\n * Configuration for {@link ITree.viewWith}.\n * @sealed @public\n */\nexport class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema>\n\timplements Required<ITreeViewConfiguration<TSchema>>\n{\n\t/**\n\t * {@inheritDoc ITreeViewConfiguration.schema}\n\t */\n\tpublic readonly schema: TSchema;\n\n\t/**\n\t * {@inheritDoc ITreeViewConfiguration.enableSchemaValidation}\n\t */\n\tpublic readonly enableSchemaValidation: boolean;\n\n\t/**\n\t * @param props - Property bag of configuration options.\n\t */\n\tpublic constructor(props: ITreeViewConfiguration<TSchema>) {\n\t\tconst config = { ...defaultTreeConfigurationOptions, ...props };\n\t\tthis.schema = config.schema;\n\t\tthis.enableSchemaValidation = config.enableSchemaValidation;\n\n\t\t// Ensure all reachable schema are marked as most derived.\n\t\t// This ensures if multiple schema extending the same schema factory generated class are present (or have been constructed, or get constructed in the future),\n\t\t// an error is reported.\n\t\twalkFieldSchema(config.schema, markSchemaMostDerived);\n\t\t// Eagerly perform this conversion to surface errors sooner.\n\t\ttoFlexSchema(config.schema);\n\t}\n}\n\nexport function walkNodeSchema(\n\tschema: TreeNodeSchema,\n\tvisitor: (schema: TreeNodeSchema) => void,\n\tvisitedSet: Set<TreeNodeSchema>,\n): void {\n\tif (visitedSet.has(schema)) {\n\t\treturn;\n\t}\n\tvisitedSet.add(schema);\n\tif (schema instanceof LeafNodeSchema) {\n\t\t// nothing to do\n\t} else if (isObjectNodeSchema(schema)) {\n\t\tfor (const field of schema.fields.values()) {\n\t\t\twalkAllowedTypes(field.allowedTypeSet, visitor, visitedSet);\n\t\t}\n\t} else {\n\t\tassert(\n\t\t\tschema.kind === NodeKind.Array || schema.kind === NodeKind.Map,\n\t\t\t0x9b3 /* invalid schema */,\n\t\t);\n\t\tconst childTypes = schema.info as ImplicitAllowedTypes;\n\t\twalkFieldSchema(childTypes, visitor, visitedSet);\n\t}\n\t// This visit is done at the end so the traversal order is most inner types first.\n\t// This was picked since when fixing errors,\n\t// working from the inner types out to the types that use them will probably go better than the reverse.\n\t// This does not however ensure all types referenced by a type are visited before it, since in recursive cases thats impossible.\n\tvisitor(schema);\n}\n\nexport function walkFieldSchema(\n\tschema: ImplicitFieldSchema,\n\tvisitor: (schema: TreeNodeSchema) => void,\n\tvisitedSet: Set<TreeNodeSchema> = new Set(),\n): void {\n\twalkAllowedTypes(normalizeFieldSchema(schema).allowedTypeSet, visitor, visitedSet);\n}\n\nexport function walkAllowedTypes(\n\tallowedTypes: Iterable<TreeNodeSchema>,\n\tvisitor: (schema: TreeNodeSchema) => void,\n\tvisitedSet: Set<TreeNodeSchema>,\n): void {\n\tfor (const childType of allowedTypes) {\n\t\twalkNodeSchema(childType, visitor, visitedSet);\n\t}\n}\n\n/**\n * An editable view of a (version control style) branch of a shared tree based on some schema.\n *\n * This schema--known as the view schema--may or may not align the stored schema of the document.\n * Information about discrepancies between the two schemas is available via {@link TreeView.compatibility | compatibility}.\n *\n * Application authors are encouraged to read [schema-evolution.md](../../docs/user-facing/schema-evolution.md) and\n * choose a schema compatibility policy that aligns with their application's needs.\n *\n * @privateRemarks\n * From an API design perspective, `upgradeSchema` could be merged into `viewWith` and/or `viewWith` could return errors explicitly on incompatible documents.\n * Such approaches would make it discoverable that out of schema handling may need to be done.\n * Doing that would however complicate trivial \"hello world\" style example slightly, as well as be a breaking API change.\n * It also seems more complex to handle invalidation with that pattern.\n * Thus this design was chosen at the risk of apps blindly accessing `root` then breaking unexpectedly when the document is incompatible.\n * @sealed @public\n */\nexport interface TreeView<TSchema extends ImplicitFieldSchema> extends IDisposable {\n\t/**\n\t * The current root of the tree.\n\t *\n\t * If the view schema not sufficiently compatible with the stored schema, accessing this will throw.\n\t * To handle this case, check {@link TreeView.compatibility | compatibility}'s {@link SchemaCompatibilityStatus.canView | canView} before using.\n\t *\n\t * To get notified about changes to this field,\n\t * use {@link TreeViewEvents.rootChanged} via `view.events.on(\"rootChanged\", callback)`.\n\t *\n\t * To get notified about changes to stored schema (which may affect compatibility between this view's schema and\n\t * the stored schema), use {@link TreeViewEvents.schemaChanged} via `view.events.on(\"schemaChanged\", callback)`.\n\t */\n\tget root(): TreeFieldFromImplicitField<TSchema>;\n\n\tset root(newRoot: InsertableTreeFieldFromImplicitField<TSchema>);\n\n\t/**\n\t * Description of the current compatibility status between the view schema and stored schema.\n\t *\n\t * {@link TreeViewEvents.schemaChanged} is fired when the compatibility status changes.\n\t */\n\treadonly compatibility: SchemaCompatibilityStatus;\n\n\t/**\n\t * When the schemas are not an exact match and {@link SchemaCompatibilityStatus.canUpgrade} is true,\n\t * this can be used to modify the stored schema to make it match the view schema.\n\t * This will update the compatibility state, and allow access to `root`.\n\t * Beware that this may impact other clients' ability to view the document depending on the application's schema compatibility policy!\n\t * @remarks\n\t * It is an error to call this when {@link SchemaCompatibilityStatus.canUpgrade} is false, and a no-op when the stored and view schema are already an exact match.\n\t * @privateRemarks\n\t * In the future, more upgrade options could be provided here.\n\t * Some options that could be added:\n\t * - check the actual document contents (not just the schema) and attempt an atomic document update if the data is compatible.\n\t * - apply converters and upgrade the document.\n\t * - apply converters to lazily to adapt the document to the requested view schema (with optional lazy schema updates or transparent conversions on write).\n\t */\n\tupgradeSchema(): void;\n\n\t/**\n\t * Initialize the tree, setting the stored schema to match this view's schema and setting the tree content.\n\t *\n\t * Only valid to call when this view's {@link SchemaCompatibilityStatus.canInitialize} is true.\n\t *\n\t * Applications should typically call this function before attaching a `SharedTree`.\n\t * @param content - The content to initialize the tree with.\n\t */\n\tinitialize(content: InsertableTreeFieldFromImplicitField<TSchema>): void;\n\n\t/**\n\t * Events for the tree.\n\t */\n\treadonly events: Listenable<TreeViewEvents>;\n}\n\n/**\n * Information about a view schema's compatibility with the document's stored schema.\n *\n * See SharedTree's README for more information about choosing a compatibility policy.\n * @sealed @public\n */\nexport interface SchemaCompatibilityStatus {\n\t/**\n\t * Whether the view schema allows exactly the same set of documents as the stored schema.\n\t *\n\t * @remarks\n\t * Equivalence here is defined in terms of allowed documents because there are some degenerate cases where schemas are not\n\t * exact matches in a strict (schema-based) sense but still allow the same documents, and the document notion is more useful to applications.\n\t *\n\t * Examples which are expressible where this may occur include:\n\t * - schema repository `A` has extra schema which schema `B` doesn't have, but they are unused (i.e. not reachable from the root schema)\n\t * - field in schema `A` has allowed field members which the corresponding field in schema `B` does not have, but those types are not constructible (ex: an object node type containing a required field with no allowed types)\n\t *\n\t * These cases are typically not interesting to applications.\n\t */\n\treadonly isEquivalent: boolean;\n\n\t/**\n\t * Whether the current view schema is sufficiently compatible with the stored schema to allow viewing tree data.\n\t * If false, {@link TreeView.root} will throw upon access.\n\t *\n\t * Currently, this field is true iff `isEquivalent` is true.\n\t * Do not rely on this:\n\t * there are near-term plans to extend support for viewing documents when the stored schema contains additional optional fields not present in the view schema.\n\t * The other two types of backward-compatible changes (field relaxations and addition of allowed field types) will eventually be supported as well,\n\t * likely through out-of-schema content adapters that the application can provide alongside their view schema.\n\t *\n\t * Be aware that even with these SharedTree limitations fixed, application logic may not correctly tolerate the documents allowable by the stored schema!\n\t * Application authors are encouraged to read docs/user-facing/schema-evolution.md and choose a schema compatibility policy that\n\t * aligns with their application's needs.\n\t *\n\t * @remarks\n\t * When the documents allowed by the view schema is a strict superset of those by the stored schema,\n\t * this is false because writes to the document using the view schema could make the document violate its stored schema.\n\t * In this case, the stored schema could be updated to match the provided view schema, allowing read-write access to the tree.\n\t * See {@link SchemaCompatibilityStatus.canUpgrade}.\n\t *\n\t * Future version of SharedTree may provide readonly access to the document in this case because that would be safe,\n\t * but this is not currently supported.\n\t *\n\t * @privateRemarks\n\t * A necessary condition for this to be true is that the documents allowed by the view schema are a subset of those allowed by the stored schema.\n\t * This is not sufficient: the simple-tree layer's read APIs do not tolerate out-of-schema data.\n\t * For example, if the view schema for a node has a required `Point` field but the stored schema has an optional `Point` field,\n\t * read APIs on the view schema do not work correctly when the document has a node with a missing `Point` field.\n\t * Similar issues happen when the view schema has a field with less allowed types than the stored schema and the document actually leverages those types.\n\t */\n\treadonly canView: boolean;\n\n\t/**\n\t * True iff the view schema supports all possible documents permitted by the stored schema.\n\t * When true, it is valid to call {@link TreeView.upgradeSchema} (though if the stored schema is already an exact match, this is a no-op).\n\t */\n\treadonly canUpgrade: boolean;\n\n\t/**\n\t * True iff the document is uninitialized (i.e. it has no schema and no content).\n\t *\n\t * To initialize the document, call {@link TreeView.initialize}.\n\t *\n\t * @remarks\n\t * It's not necessary to check this field before calling {@link TreeView.initialize} in most scenarios; application authors typically know from\n\t * context that they're in a flow which creates a new `SharedTree` and would like to initialize it.\n\t */\n\treadonly canInitialize: boolean;\n\n\t// TODO: Consider extending this status to include:\n\t// - application-defined metadata about the stored schema\n\t// - details about the differences between the stored and view schema sufficient for implementing \"safe mismatch\" policies\n}\n\n/**\n * Events for {@link TreeView}.\n * @sealed @public\n */\nexport interface TreeViewEvents {\n\t/**\n\t * Raised whenever {@link TreeView.root} is invalidated.\n\t *\n\t * This includes changes to the document schema.\n\t * It also includes changes to the field containing the root such as setting or clearing an optional root or changing which node is the root.\n\t * This does NOT include changes to the content (fields/children) of the root node: for that case subscribe to events on the root node.\n\t */\n\trootChanged(): void;\n\n\t/**\n\t * The stored schema for the document has changed.\n\t * This may affect the compatibility between the view schema and the stored schema, and thus the ability to use the view.\n\t *\n\t * @remarks\n\t * This event implies that the old {@link TreeView.root} is no longer valid, but applications need not handle that separately:\n\t * {@link TreeViewEvents.rootChanged} will be fired after this event.\n\t */\n\tschemaChanged(): void;\n\n\t/**\n\t * Fired when:\n\t * - a local commit is applied outside of a transaction\n\t * - a local transaction is committed\n\t *\n\t * The event is not fired when:\n\t * - a local commit is applied within a transaction\n\t * - a remote commit is applied\n\t *\n\t * @param data - information about the commit that was applied\n\t * @param getRevertible - a function provided that allows users to get a revertible for the commit that was applied. If not provided,\n\t * this commit is not revertible.\n\t */\n\tcommitApplied(data: CommitMetadata, getRevertible?: RevertibleFactory): void;\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { type TreeStatus } from "../feature-libraries/index.js";
6
6
  import { NodeKind, type TreeLeafValue, type TreeNodeSchema, type ImplicitAllowedTypes, type TreeNodeFromImplicitAllowedTypes } from "./schemaTypes.js";
7
- import type { TreeNode } from "./types.js";
7
+ import type { TreeNode, TreeChangeEvents } from "./types.js";
8
8
  /**
9
9
  * Provides various functions for analyzing {@link TreeNode}s.
10
10
  * * @remarks
@@ -55,7 +55,7 @@ export interface TreeNodeApi {
55
55
  /**
56
56
  * Returns the {@link TreeStatus} of the given node.
57
57
  */
58
- readonly status: (node: TreeNode) => TreeStatus;
58
+ status(node: TreeNode): TreeStatus;
59
59
  /**
60
60
  * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.
61
61
  * @remarks
@@ -83,77 +83,4 @@ export declare const treeNodeApi: TreeNodeApi;
83
83
  * Returns undefined for other values.
84
84
  */
85
85
  export declare function tryGetSchema<T>(value: T): undefined | TreeNodeSchema<string, NodeKind, unknown, T>;
86
- /**
87
- * A collection of events that can be emitted by a {@link TreeNode}.
88
- *
89
- * @privateRemarks
90
- * TODO: add a way to subscribe to a specific field (for nodeChanged and treeChanged).
91
- * Probably have object node and map node specific APIs for this.
92
- *
93
- * TODO: ensure that subscription API for fields aligns with API for subscribing to the root.
94
- *
95
- * TODO: add more wider area (avoid needing tons of nodeChanged registration) events for use-cases other than treeChanged.
96
- * Some ideas:
97
- *
98
- * - treeChanged, but with some subtrees/fields/paths excluded
99
- * - helper to batch several nodeChanged calls to a treeChanged scope
100
- * - parent change (ex: registration on the parent field for a specific index: maybe allow it for a range. Ex: node event takes optional field and optional index range?)
101
- * - new content inserted into subtree. Either provide event for this and/or enough info to treeChanged to find and search the new sub-trees.
102
- * Add separate (non event related) API to efficiently scan tree for given set of types (using low level cursor and schema based filtering)
103
- * to allow efficiently searching for new content (and initial content) of a given type.
104
- *
105
- * @sealed @public
106
- */
107
- export interface TreeChangeEvents {
108
- /**
109
- * Emitted by a node after a batch of changes has been applied to the tree, if a change affected the node, where a
110
- * change is:
111
- *
112
- * - For an object node, when the value of one of its properties changes (i.e., the property's value is set
113
- * to something else, including `undefined`).
114
- *
115
- * - For an array node, when an element is added, removed, or moved.
116
- *
117
- * - For a map node, when an entry is added, updated, or removed.
118
- *
119
- * @remarks
120
- * This event is not emitted when:
121
- *
122
- * - Properties of a child node change. Notably, updates to an array node or a map node (like adding or removing
123
- * elements/entries) will emit this event on the array/map node itself, but not on the node that contains the
124
- * array/map node as one of its properties.
125
- *
126
- * - The node is moved to a different location in the tree or removed from the tree.
127
- * In this case the event is emitted on the _parent_ node, not the node itself.
128
- *
129
- * For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in
130
- * the client that made the original edit.
131
- *
132
- * When it is emitted, the tree is guaranteed to be in-schema.
133
- *
134
- * @privateRemarks
135
- * This event occurs whenever the apparent contents of the node instance change, regardless of what caused the change.
136
- * For example, it will fire when the local client reassigns a child, when part of a remote edit is applied to the
137
- * node, or when the node has to be updated due to resolution of a merge conflict
138
- * (for example a previously applied local change might be undone, then reapplied differently or not at all).
139
- */
140
- nodeChanged(): void;
141
- /**
142
- * Emitted by a node after a batch of changes has been applied to the tree, when something changed anywhere in the
143
- * subtree rooted at it.
144
- *
145
- * @remarks
146
- * This event is not emitted when the node itself is moved to a different location in the tree or removed from the tree.
147
- * In that case it is emitted on the _parent_ node, not the node itself.
148
- *
149
- * The node itself is part of the subtree, so this event will be emitted even if the only changes are to the properties
150
- * of the node itself.
151
- *
152
- * For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in
153
- * the client that made the original edit.
154
- *
155
- * When it is emitted, the tree is guaranteed to be in-schema.
156
- */
157
- treeChanged(): void;
158
- }
159
86
  //# sourceMappingURL=treeNodeApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"treeNodeApi.d.ts","sourceRoot":"","sources":["../../src/simple-tree/treeNodeApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAGN,KAAK,UAAU,EAGf,MAAM,+BAA+B,CAAC;AAMvC,OAAO,EACN,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,cAAc,EAGnB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EACrC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAW3C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,aAAa,EACxC,IAAI,EAAE,CAAC,GACL,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAEhD;;;;;;;;OAQG;IACH,EAAE,CAAC,OAAO,SAAS,oBAAoB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,GACb,KAAK,IAAI,gCAAgC,CAAC,OAAO,CAAC,CAAC;IAEtD;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAE7C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAErC;;;;;;;OAOG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAClC,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,MAAM,IAAI,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,UAAU,CAAC;IAEhD;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,WAgGzB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,GACN,SAAS,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAwB1D;AAmDD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,WAAW,IAAI,IAAI,CAAC;IAEpB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,IAAI,IAAI,CAAC;CACpB"}
1
+ {"version":3,"file":"treeNodeApi.d.ts","sourceRoot":"","sources":["../../src/simple-tree/treeNodeApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAEN,KAAK,UAAU,EAIf,MAAM,+BAA+B,CAAC;AAMvC,OAAO,EACN,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,cAAc,EAGnB,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,EACrC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAY7D;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,aAAa,EACxC,IAAI,EAAE,CAAC,GACL,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAEhD;;;;;;;;OAQG;IACH,EAAE,CAAC,OAAO,SAAS,oBAAoB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,GACb,KAAK,IAAI,gCAAgC,CAAC,OAAO,CAAC,CAAC;IAEtD;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAE7C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAErC;;;;;;;OAOG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAClC,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,MAAM,IAAI,CAAC;IAEd;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAEnC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,WAwFzB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,GACN,SAAS,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAwB1D"}
@@ -2,12 +2,12 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
5
+ import { assert } from "@fluidframework/core-utils/internal";
6
6
  import { Multiplicity, rootFieldKey } from "../core/index.js";
7
- import { FieldKinds, isLazy, isTreeValue, } from "../feature-libraries/index.js";
7
+ import { isLazy, isTreeValue, FlexObjectNodeSchema, } from "../feature-libraries/index.js";
8
8
  import { fail, extractFromOpaque, isReadonlyArray } from "../util/index.js";
9
9
  import { getOrCreateNodeProxy, isTreeNode } from "./proxies.js";
10
- import { getFlexNode } from "./proxyBinding.js";
10
+ import { getFlexNode, getKernel } from "./proxyBinding.js";
11
11
  import { tryGetSimpleNodeSchema } from "./schemaCaching.js";
12
12
  import { NodeKind, FieldSchema, } from "./schemaTypes.js";
13
13
  import { booleanSchema, handleSchema, nullSchema, numberSchema, stringSchema, } from "./leafNodeSchema.js";
@@ -17,7 +17,7 @@ import { UsageError } from "@fluidframework/telemetry-utils/internal";
17
17
  * The `Tree` object holds various functions for analyzing {@link TreeNode}s.
18
18
  */
19
19
  export const treeNodeApi = {
20
- parent: (node) => {
20
+ parent(node) {
21
21
  const editNode = getFlexNode(node).parentField.parent.parent;
22
22
  if (editNode === undefined) {
23
23
  return undefined;
@@ -26,7 +26,7 @@ export const treeNodeApi = {
26
26
  assert(!isTreeValue(output), 0x87f /* Parent can't be a leaf, so it should be a node not a value */);
27
27
  return output;
28
28
  },
29
- key: (node) => {
29
+ key(node) {
30
30
  // If the parent is undefined, then this node is under the root field,
31
31
  // so we know its key is the special root one.
32
32
  const parent = treeNodeApi.parent(node);
@@ -41,21 +41,13 @@ export const treeNodeApi = {
41
41
  const viewKey = getViewKeyFromStoredKey(parentSchema, storedKey);
42
42
  return viewKey;
43
43
  },
44
- on: (node, eventName, listener) => {
45
- const flex = getFlexNode(node);
46
- switch (eventName) {
47
- case "nodeChanged":
48
- return flex.on("nodeChanged", listener);
49
- case "treeChanged":
50
- return flex.on("treeChanged", listener);
51
- default:
52
- return unreachableCase(eventName);
53
- }
44
+ on(node, eventName, listener) {
45
+ return getKernel(node).on(eventName, listener);
54
46
  },
55
- status: (node) => {
56
- return getFlexNode(node, true).treeStatus();
47
+ status(node) {
48
+ return getKernel(node).getStatus();
57
49
  },
58
- is: (value, schema) => {
50
+ is(value, schema) {
59
51
  const actualSchema = tryGetSchema(value);
60
52
  if (actualSchema === undefined) {
61
53
  return false;
@@ -78,21 +70,21 @@ export const treeNodeApi = {
78
70
  },
79
71
  shortId(node) {
80
72
  const flexNode = getFlexNode(node);
81
- let shortId;
82
- for (const field of flexNode.boxedIterator()) {
83
- if (field.schema.kind === FieldKinds.identifier) {
84
- if (shortId !== undefined) {
85
- throw new UsageError("shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.");
86
- }
87
- const identifier = field.boxedAt(0);
73
+ const flexSchema = flexNode.schema;
74
+ const identifierFieldKeys = flexSchema instanceof FlexObjectNodeSchema ? flexSchema.identifierFieldKeys : [];
75
+ switch (identifierFieldKeys.length) {
76
+ case 0:
77
+ return undefined;
78
+ case 1: {
79
+ const identifier = flexNode.tryGetField(identifierFieldKeys[0])?.boxedAt(0);
88
80
  assert(identifier !== undefined, 0x927 /* The identifier must exist */);
89
81
  const identifierValue = identifier.value;
90
82
  const localNodeKey = identifier.context.nodeKeyManager.tryLocalizeNodeKey(identifierValue);
91
- shortId =
92
- localNodeKey !== undefined ? extractFromOpaque(localNodeKey) : identifierValue;
83
+ return localNodeKey !== undefined ? extractFromOpaque(localNodeKey) : identifierValue;
93
84
  }
85
+ default:
86
+ throw new UsageError("shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.");
94
87
  }
95
- return shortId;
96
88
  },
97
89
  };
98
90
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"treeNodeApi.js","sourceRoot":"","sources":["../../src/simple-tree/treeNodeApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EACN,UAAU,EAGV,MAAM,EACN,WAAW,GACX,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EACN,QAAQ,EAIR,WAAW,GAGX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,aAAa,EACb,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAuFtE;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAgB;IACvC,MAAM,EAAE,CAAC,IAAc,EAAwB,EAAE;QAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QAC7D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,CACL,CAAC,WAAW,CAAC,MAAM,CAAC,EACpB,KAAK,CAAC,gEAAgE,CACtE,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IACD,GAAG,EAAE,CAAC,IAAc,EAAE,EAAE;QACvB,sEAAsE;QACtE,8CAA8C;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,YAAY,CAAC;QACrB,CAAC;QAED,+DAA+D;QAC/D,mGAAmG;QACnG,wGAAwG;QACxG,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,uBAAuB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACjE,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,EAAE,EAAE,CACH,IAAc,EACd,SAAY,EACZ,QAA6B,EAC5B,EAAE;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,QAAQ,SAAS,EAAE,CAAC;YACnB,KAAK,aAAa;gBACjB,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACzC,KAAK,aAAa;gBACjB,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACzC;gBACC,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;IACF,CAAC;IACD,MAAM,EAAE,CAAC,IAAc,EAAE,EAAE;QAC1B,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;IAC7C,CAAC;IACD,EAAE,EAAE,CACH,KAAc,EACd,MAAe,EACsC,EAAE;QACvD,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,eAAe,CAA2B,MAAM,CAAC,EAAE,CAAC;YACvD,KAAK,MAAM,YAAY,IAAI,MAAM,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;gBACxE,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;oBACjC,OAAO,IAAI,CAAC;gBACb,CAAC;YACF,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;aAAM,CAAC;YACP,OAAQ,MAAyB,KAAK,YAAY,CAAC;QACpD,CAAC;IACF,CAAC;IACD,MAAM,CACL,IAAO;QAEP,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,IAAc;QACrB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,OAAoC,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC;YAC9C,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;gBACjD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC3B,MAAM,IAAI,UAAU,CACnB,yIAAyI,CACzI,CAAC;gBACH,CAAC;gBACD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACpC,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACxE,MAAM,eAAe,GAAG,UAAU,CAAC,KAAe,CAAC;gBACnD,MAAM,YAAY,GACjB,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;gBAEvE,OAAO;oBACN,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;YACjF,CAAC;QACF,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;CACD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC3B,KAAQ;IAGR,QAAQ,OAAO,KAAK,EAAE,CAAC;QACtB,KAAK,QAAQ;YACZ,OAAO,YAAoB,CAAC;QAC7B,KAAK,QAAQ;YACZ,OAAO,YAAoB,CAAC;QAC7B,KAAK,SAAS;YACb,OAAO,aAAqB,CAAC;QAC9B,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvB,oGAAoG;gBACpG,OAAO,sBAAsB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAS,CAAC;YAClE,CAAC;YACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,UAAkB,CAAC;YAC3B,CAAC;YACD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,YAAoB,CAAC;YAC7B,CAAC;QACF,CAAC;QACD;YACC,OAAO,SAAS,CAAC;IACnB,CAAC;AACF,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAAc;IACnC,wGAAwG;IACxG,eAAe;IACf,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC;IAClD,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC3E,wCAAwC;QACxC,OAAO,WAAW,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,yGAAyG;IACzG,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC/B,MAAsB,EACtB,SAA0B;IAE1B,6GAA6G;IAC7G,4EAA4E;IAC5E,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAA2C,CAAC;IAElE,cAAc;IACd,6DAA6D;IAC7D,mGAAmG;IACnG,yIAAyI;IACzI,6DAA6D;IAC7D,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7D,IAAI,WAAW,YAAY,WAAW,IAAI,WAAW,CAAC,KAAK,EAAE,GAAG,KAAK,SAAS,EAAE,CAAC;YAChF,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\n\nimport { Multiplicity, rootFieldKey } from \"../core/index.js\";\nimport {\n\tFieldKinds,\n\ttype LazyItem,\n\ttype TreeStatus,\n\tisLazy,\n\tisTreeValue,\n} from \"../feature-libraries/index.js\";\nimport { fail, extractFromOpaque, isReadonlyArray } from \"../util/index.js\";\n\nimport { getOrCreateNodeProxy, isTreeNode } from \"./proxies.js\";\nimport { getFlexNode } from \"./proxyBinding.js\";\nimport { tryGetSimpleNodeSchema } from \"./schemaCaching.js\";\nimport {\n\tNodeKind,\n\ttype TreeLeafValue,\n\ttype TreeNodeSchema,\n\ttype ImplicitFieldSchema,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype TreeNodeFromImplicitAllowedTypes,\n} from \"./schemaTypes.js\";\nimport type { TreeNode } from \"./types.js\";\nimport {\n\tbooleanSchema,\n\thandleSchema,\n\tnullSchema,\n\tnumberSchema,\n\tstringSchema,\n} from \"./leafNodeSchema.js\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * Provides various functions for analyzing {@link TreeNode}s.\n * * @remarks\n * This type should only be used via the public `Tree` export.\n * @privateRemarks\n * Due to limitations of API-Extractor link resolution, this type can't be moved into internalTypes but should be considered just an implementation detail of the `Tree` export.\n *\n * Inlining the typing of this interface onto the `Tree` object provides slightly different .d.ts generation,\n * which avoids typescript expanding the type of TreeNodeSchema and thus encountering\n * https://github.com/microsoft/rushstack/issues/1958.\n * @sealed @public\n */\nexport interface TreeNodeApi {\n\t/**\n\t * The schema information for this node.\n\t */\n\tschema<T extends TreeNode | TreeLeafValue>(\n\t\tnode: T,\n\t): TreeNodeSchema<string, NodeKind, unknown, T>;\n\n\t/**\n\t * Narrow the type of the given value if it satisfies the given schema.\n\t * @example\n\t * ```ts\n\t * if (node.is(myNode, Point)) {\n\t * const y = myNode.y; // `myNode` is now known to satisfy the `Point` schema and therefore has a `y` coordinate.\n\t * }\n\t * ```\n\t */\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema>;\n\n\t/**\n\t * Return the node under which this node resides in the tree (or undefined if this is a root node of the tree).\n\t */\n\tparent(node: TreeNode): TreeNode | undefined;\n\n\t/**\n\t * The key of the given node under its parent.\n\t * @remarks\n\t * If `node` is an element in a {@link (TreeArrayNode:interface)}, this returns the index of `node` in the array node (a `number`).\n\t * Otherwise, this returns the key of the field that it is under (a `string`).\n\t */\n\tkey(node: TreeNode): string | number;\n\n\t/**\n\t * Register an event listener on the given node.\n\t * @param node - The node whose events should be subscribed to.\n\t * @param eventName - Which event to subscribe to.\n\t * @param listener - The callback to trigger for the event. The tree can be read during the callback, but it is invalid to modify the tree during this callback.\n\t * @returns A callback function which will deregister the event.\n\t * This callback should be called only once.\n\t */\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): () => void;\n\n\t/**\n\t * Returns the {@link TreeStatus} of the given node.\n\t */\n\treadonly status: (node: TreeNode) => TreeStatus;\n\n\t/**\n\t * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.\n\t * @remarks\n\t * 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.\n\t * 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.\n\t *\n\t * If the node's identifier is any other user-provided string, then this will return that string.\n\t *\n\t * If the node has no identifier (that is, it has no {@link SchemaFactory.identifier | identifier} field), then this returns `undefined`.\n\t *\n\t * If the node has more than one identifier, then this will throw an error.\n\t *\n\t * The returned integer must not be serialized or preserved outside of the current process.\n\t * 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.\n\t * 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.\n\t */\n\tshortId(node: TreeNode): number | string | undefined;\n}\n\n/**\n * The `Tree` object holds various functions for analyzing {@link TreeNode}s.\n */\nexport const treeNodeApi: TreeNodeApi = {\n\tparent: (node: TreeNode): TreeNode | undefined => {\n\t\tconst editNode = getFlexNode(node).parentField.parent.parent;\n\t\tif (editNode === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst output = getOrCreateNodeProxy(editNode);\n\t\tassert(\n\t\t\t!isTreeValue(output),\n\t\t\t0x87f /* Parent can't be a leaf, so it should be a node not a value */,\n\t\t);\n\t\treturn output;\n\t},\n\tkey: (node: TreeNode) => {\n\t\t// If the parent is undefined, then this node is under the root field,\n\t\t// so we know its key is the special root one.\n\t\tconst parent = treeNodeApi.parent(node);\n\t\tif (parent === undefined) {\n\t\t\treturn rootFieldKey;\n\t\t}\n\n\t\t// The flex-domain strictly operates in terms of \"stored keys\".\n\t\t// To find the associated developer-facing \"view key\", we need to look up the field associated with\n\t\t// the stored key from the flex-domain, and get view key its simple-domain counterpart was created with.\n\t\tconst storedKey = getStoredKey(node);\n\t\tconst parentSchema = treeNodeApi.schema(parent);\n\t\tconst viewKey = getViewKeyFromStoredKey(parentSchema, storedKey);\n\t\treturn viewKey;\n\t},\n\ton: <K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t) => {\n\t\tconst flex = getFlexNode(node);\n\t\tswitch (eventName) {\n\t\t\tcase \"nodeChanged\":\n\t\t\t\treturn flex.on(\"nodeChanged\", listener);\n\t\t\tcase \"treeChanged\":\n\t\t\t\treturn flex.on(\"treeChanged\", listener);\n\t\t\tdefault:\n\t\t\t\treturn unreachableCase(eventName);\n\t\t}\n\t},\n\tstatus: (node: TreeNode) => {\n\t\treturn getFlexNode(node, true).treeStatus();\n\t},\n\tis: <TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema> => {\n\t\tconst actualSchema = tryGetSchema(value);\n\t\tif (actualSchema === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\tif (isReadonlyArray<LazyItem<TreeNodeSchema>>(schema)) {\n\t\t\tfor (const singleSchema of schema) {\n\t\t\t\tconst testSchema = isLazy(singleSchema) ? singleSchema() : singleSchema;\n\t\t\t\tif (testSchema === actualSchema) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} else {\n\t\t\treturn (schema as TreeNodeSchema) === actualSchema;\n\t\t}\n\t},\n\tschema<T extends TreeNode | TreeLeafValue>(\n\t\tnode: T,\n\t): TreeNodeSchema<string, NodeKind, unknown, T> {\n\t\treturn tryGetSchema(node) ?? fail(\"Not a tree node\");\n\t},\n\tshortId(node: TreeNode): number | string | undefined {\n\t\tconst flexNode = getFlexNode(node);\n\t\tlet shortId: number | string | undefined;\n\t\tfor (const field of flexNode.boxedIterator()) {\n\t\t\tif (field.schema.kind === FieldKinds.identifier) {\n\t\t\t\tif (shortId !== undefined) {\n\t\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\t\"shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst identifier = field.boxedAt(0);\n\t\t\t\tassert(identifier !== undefined, 0x927 /* The identifier must exist */);\n\t\t\t\tconst identifierValue = identifier.value as string;\n\t\t\t\tconst localNodeKey =\n\t\t\t\t\tidentifier.context.nodeKeyManager.tryLocalizeNodeKey(identifierValue);\n\n\t\t\t\tshortId =\n\t\t\t\t\tlocalNodeKey !== undefined ? extractFromOpaque(localNodeKey) : identifierValue;\n\t\t\t}\n\t\t}\n\n\t\treturn shortId;\n\t},\n};\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode} or a {@link TreeLeafValue}.\n * Returns undefined for other values.\n */\nexport function tryGetSchema<T>(\n\tvalue: T,\n): undefined | TreeNodeSchema<string, NodeKind, unknown, T> {\n\ttype TOut = TreeNodeSchema<string, NodeKind, unknown, T>;\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\t\treturn stringSchema as TOut;\n\t\tcase \"number\":\n\t\t\treturn numberSchema as TOut;\n\t\tcase \"boolean\":\n\t\t\treturn booleanSchema as TOut;\n\t\tcase \"object\": {\n\t\t\tif (isTreeNode(value)) {\n\t\t\t\t// This case could be optimized, for example by placing the simple schema in a symbol on tree nodes.\n\t\t\t\treturn tryGetSimpleNodeSchema(getFlexNode(value).schema) as TOut;\n\t\t\t}\n\t\t\tif (value === null) {\n\t\t\t\treturn nullSchema as TOut;\n\t\t\t}\n\t\t\tif (isFluidHandle(value)) {\n\t\t\t\treturn handleSchema as TOut;\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Gets the stored key with which the provided node is associated in the parent.\n */\nfunction getStoredKey(node: TreeNode): string | number {\n\t// Note: the flex domain strictly works with \"stored keys\", and knows nothing about the developer-facing\n\t// \"view keys\".\n\tconst parentField = getFlexNode(node).parentField;\n\tif (parentField.parent.schema.kind.multiplicity === Multiplicity.Sequence) {\n\t\t// The parent of `node` is an array node\n\t\treturn parentField.index;\n\t}\n\n\t// The parent of `node` is an object, a map, or undefined (and therefore `node` is a root/detached node).\n\treturn parentField.parent.key;\n}\n\n/**\n * Given a node schema, gets the view key corresponding with the provided {@link FieldProps.key | stored key}.\n */\nfunction getViewKeyFromStoredKey(\n\tschema: TreeNodeSchema,\n\tstoredKey: string | number,\n): string | number {\n\t// Only object nodes have the concept of a \"stored key\", differentiated from the developer-facing \"view key\".\n\t// For any other kind of node, the stored key and the view key are the same.\n\tif (schema.kind !== NodeKind.Object) {\n\t\treturn storedKey;\n\t}\n\n\tconst fields = schema.info as Record<string, ImplicitFieldSchema>;\n\n\t// Invariants:\n\t// - The set of all view keys under an object must be unique.\n\t// - The set of all stored keys (including those implicitly created from view keys) must be unique.\n\t// To find the view key associated with the provided stored key, first check for any stored key matches (which are optionally populated).\n\t// If we don't find any, then search for a matching view key.\n\tfor (const [viewKey, fieldSchema] of Object.entries(fields)) {\n\t\tif (fieldSchema instanceof FieldSchema && fieldSchema.props?.key === storedKey) {\n\t\t\treturn viewKey;\n\t\t}\n\t}\n\n\tif (fields[storedKey] === undefined) {\n\t\tfail(\"Existing stored key should always map to a view key\");\n\t}\n\n\treturn storedKey;\n}\n\n/**\n * A collection of events that can be emitted by a {@link TreeNode}.\n *\n * @privateRemarks\n * TODO: add a way to subscribe to a specific field (for nodeChanged and treeChanged).\n * Probably have object node and map node specific APIs for this.\n *\n * TODO: ensure that subscription API for fields aligns with API for subscribing to the root.\n *\n * TODO: add more wider area (avoid needing tons of nodeChanged registration) events for use-cases other than treeChanged.\n * Some ideas:\n *\n * - treeChanged, but with some subtrees/fields/paths excluded\n * - helper to batch several nodeChanged calls to a treeChanged scope\n * - parent change (ex: registration on the parent field for a specific index: maybe allow it for a range. Ex: node event takes optional field and optional index range?)\n * - new content inserted into subtree. Either provide event for this and/or enough info to treeChanged to find and search the new sub-trees.\n * Add separate (non event related) API to efficiently scan tree for given set of types (using low level cursor and schema based filtering)\n * to allow efficiently searching for new content (and initial content) of a given type.\n *\n * @sealed @public\n */\nexport interface TreeChangeEvents {\n\t/**\n\t * Emitted by a node after a batch of changes has been applied to the tree, if a change affected the node, where a\n\t * change is:\n\t *\n\t * - For an object node, when the value of one of its properties changes (i.e., the property's value is set\n\t * to something else, including `undefined`).\n\t *\n\t * - For an array node, when an element is added, removed, or moved.\n\t *\n\t * - For a map node, when an entry is added, updated, or removed.\n\t *\n\t * @remarks\n\t * This event is not emitted when:\n\t *\n\t * - Properties of a child node change. Notably, updates to an array node or a map node (like adding or removing\n\t * elements/entries) will emit this event on the array/map node itself, but not on the node that contains the\n\t * array/map node as one of its properties.\n\t *\n\t * - The node is moved to a different location in the tree or removed from the tree.\n\t * In this case the event is emitted on the _parent_ node, not the node itself.\n\t *\n\t * For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in\n\t * the client that made the original edit.\n\t *\n\t * When it is emitted, the tree is guaranteed to be in-schema.\n\t *\n\t * @privateRemarks\n\t * This event occurs whenever the apparent contents of the node instance change, regardless of what caused the change.\n\t * For example, it will fire when the local client reassigns a child, when part of a remote edit is applied to the\n\t * node, or when the node has to be updated due to resolution of a merge conflict\n\t * (for example a previously applied local change might be undone, then reapplied differently or not at all).\n\t */\n\tnodeChanged(): void;\n\n\t/**\n\t * Emitted by a node after a batch of changes has been applied to the tree, when something changed anywhere in the\n\t * subtree rooted at it.\n\t *\n\t * @remarks\n\t * This event is not emitted when the node itself is moved to a different location in the tree or removed from the tree.\n\t * In that case it is emitted on the _parent_ node, not the node itself.\n\t *\n\t * The node itself is part of the subtree, so this event will be emitted even if the only changes are to the properties\n\t * of the node itself.\n\t *\n\t * For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in\n\t * the client that made the original edit.\n\t *\n\t * When it is emitted, the tree is guaranteed to be in-schema.\n\t */\n\ttreeChanged(): void;\n}\n"]}
1
+ {"version":3,"file":"treeNodeApi.js","sourceRoot":"","sources":["../../src/simple-tree/treeNodeApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAGN,MAAM,EACN,WAAW,EACX,oBAAoB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EACN,QAAQ,EAIR,WAAW,GAGX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,aAAa,EACb,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAwFtE;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAgB;IACvC,MAAM,CAAC,IAAc;QACpB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QAC7D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,CACL,CAAC,WAAW,CAAC,MAAM,CAAC,EACpB,KAAK,CAAC,gEAAgE,CACtE,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IACD,GAAG,CAAC,IAAc;QACjB,sEAAsE;QACtE,8CAA8C;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,YAAY,CAAC;QACrB,CAAC;QAED,+DAA+D;QAC/D,mGAAmG;QACnG,wGAAwG;QACxG,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,uBAAuB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACjE,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,EAAE,CACD,IAAc,EACd,SAAY,EACZ,QAA6B;QAE7B,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,CAAC,IAAc;QACpB,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;IACpC,CAAC;IACD,EAAE,CACD,KAAc,EACd,MAAe;QAEf,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,eAAe,CAA2B,MAAM,CAAC,EAAE,CAAC;YACvD,KAAK,MAAM,YAAY,IAAI,MAAM,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;gBACxE,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;oBACjC,OAAO,IAAI,CAAC;gBACb,CAAC;YACF,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;aAAM,CAAC;YACP,OAAQ,MAAyB,KAAK,YAAY,CAAC;QACpD,CAAC;IACF,CAAC;IACD,MAAM,CACL,IAAO;QAEP,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,IAAc;QACrB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC;QACnC,MAAM,mBAAmB,GACxB,UAAU,YAAY,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;QAElF,QAAQ,mBAAmB,CAAC,MAAM,EAAE,CAAC;YACpC,KAAK,CAAC;gBACL,OAAO,SAAS,CAAC;YAClB,KAAK,CAAC,CAAC,CAAC,CAAC;gBACR,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC5E,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACxE,MAAM,eAAe,GAAG,UAAU,CAAC,KAAe,CAAC;gBACnD,MAAM,YAAY,GACjB,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;gBACvE,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;YACvF,CAAC;YACD;gBACC,MAAM,IAAI,UAAU,CACnB,yIAAyI,CACzI,CAAC;QACJ,CAAC;IACF,CAAC;CACD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC3B,KAAQ;IAGR,QAAQ,OAAO,KAAK,EAAE,CAAC;QACtB,KAAK,QAAQ;YACZ,OAAO,YAAoB,CAAC;QAC7B,KAAK,QAAQ;YACZ,OAAO,YAAoB,CAAC;QAC7B,KAAK,SAAS;YACb,OAAO,aAAqB,CAAC;QAC9B,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvB,oGAAoG;gBACpG,OAAO,sBAAsB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAS,CAAC;YAClE,CAAC;YACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,UAAkB,CAAC;YAC3B,CAAC;YACD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,YAAoB,CAAC;YAC7B,CAAC;QACF,CAAC;QACD;YACC,OAAO,SAAS,CAAC;IACnB,CAAC;AACF,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAAc;IACnC,wGAAwG;IACxG,eAAe;IACf,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC;IAClD,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC3E,wCAAwC;QACxC,OAAO,WAAW,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,yGAAyG;IACzG,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC/B,MAAsB,EACtB,SAA0B;IAE1B,6GAA6G;IAC7G,4EAA4E;IAC5E,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAA2C,CAAC;IAElE,cAAc;IACd,6DAA6D;IAC7D,mGAAmG;IACnG,yIAAyI;IACzI,6DAA6D;IAC7D,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7D,IAAI,WAAW,YAAY,WAAW,IAAI,WAAW,CAAC,KAAK,EAAE,GAAG,KAAK,SAAS,EAAE,CAAC;YAChF,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { Multiplicity, rootFieldKey } from \"../core/index.js\";\nimport {\n\ttype LazyItem,\n\ttype TreeStatus,\n\tisLazy,\n\tisTreeValue,\n\tFlexObjectNodeSchema,\n} from \"../feature-libraries/index.js\";\nimport { fail, extractFromOpaque, isReadonlyArray } from \"../util/index.js\";\n\nimport { getOrCreateNodeProxy, isTreeNode } from \"./proxies.js\";\nimport { getFlexNode, getKernel } from \"./proxyBinding.js\";\nimport { tryGetSimpleNodeSchema } from \"./schemaCaching.js\";\nimport {\n\tNodeKind,\n\ttype TreeLeafValue,\n\ttype TreeNodeSchema,\n\ttype ImplicitFieldSchema,\n\tFieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype TreeNodeFromImplicitAllowedTypes,\n} from \"./schemaTypes.js\";\nimport type { TreeNode, TreeChangeEvents } from \"./types.js\";\nimport {\n\tbooleanSchema,\n\thandleSchema,\n\tnullSchema,\n\tnumberSchema,\n\tstringSchema,\n} from \"./leafNodeSchema.js\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport type { Off } from \"../events/index.js\";\n\n/**\n * Provides various functions for analyzing {@link TreeNode}s.\n * * @remarks\n * This type should only be used via the public `Tree` export.\n * @privateRemarks\n * Due to limitations of API-Extractor link resolution, this type can't be moved into internalTypes but should be considered just an implementation detail of the `Tree` export.\n *\n * Inlining the typing of this interface onto the `Tree` object provides slightly different .d.ts generation,\n * which avoids typescript expanding the type of TreeNodeSchema and thus encountering\n * https://github.com/microsoft/rushstack/issues/1958.\n * @sealed @public\n */\nexport interface TreeNodeApi {\n\t/**\n\t * The schema information for this node.\n\t */\n\tschema<T extends TreeNode | TreeLeafValue>(\n\t\tnode: T,\n\t): TreeNodeSchema<string, NodeKind, unknown, T>;\n\n\t/**\n\t * Narrow the type of the given value if it satisfies the given schema.\n\t * @example\n\t * ```ts\n\t * if (node.is(myNode, Point)) {\n\t * const y = myNode.y; // `myNode` is now known to satisfy the `Point` schema and therefore has a `y` coordinate.\n\t * }\n\t * ```\n\t */\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema>;\n\n\t/**\n\t * Return the node under which this node resides in the tree (or undefined if this is a root node of the tree).\n\t */\n\tparent(node: TreeNode): TreeNode | undefined;\n\n\t/**\n\t * The key of the given node under its parent.\n\t * @remarks\n\t * If `node` is an element in a {@link (TreeArrayNode:interface)}, this returns the index of `node` in the array node (a `number`).\n\t * Otherwise, this returns the key of the field that it is under (a `string`).\n\t */\n\tkey(node: TreeNode): string | number;\n\n\t/**\n\t * Register an event listener on the given node.\n\t * @param node - The node whose events should be subscribed to.\n\t * @param eventName - Which event to subscribe to.\n\t * @param listener - The callback to trigger for the event. The tree can be read during the callback, but it is invalid to modify the tree during this callback.\n\t * @returns A callback function which will deregister the event.\n\t * This callback should be called only once.\n\t */\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): () => void;\n\n\t/**\n\t * Returns the {@link TreeStatus} of the given node.\n\t */\n\tstatus(node: TreeNode): TreeStatus;\n\n\t/**\n\t * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.\n\t * @remarks\n\t * 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.\n\t * 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.\n\t *\n\t * If the node's identifier is any other user-provided string, then this will return that string.\n\t *\n\t * If the node has no identifier (that is, it has no {@link SchemaFactory.identifier | identifier} field), then this returns `undefined`.\n\t *\n\t * If the node has more than one identifier, then this will throw an error.\n\t *\n\t * The returned integer must not be serialized or preserved outside of the current process.\n\t * 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.\n\t * 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.\n\t */\n\tshortId(node: TreeNode): number | string | undefined;\n}\n\n/**\n * The `Tree` object holds various functions for analyzing {@link TreeNode}s.\n */\nexport const treeNodeApi: TreeNodeApi = {\n\tparent(node: TreeNode): TreeNode | undefined {\n\t\tconst editNode = getFlexNode(node).parentField.parent.parent;\n\t\tif (editNode === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst output = getOrCreateNodeProxy(editNode);\n\t\tassert(\n\t\t\t!isTreeValue(output),\n\t\t\t0x87f /* Parent can't be a leaf, so it should be a node not a value */,\n\t\t);\n\t\treturn output;\n\t},\n\tkey(node: TreeNode): string | number {\n\t\t// If the parent is undefined, then this node is under the root field,\n\t\t// so we know its key is the special root one.\n\t\tconst parent = treeNodeApi.parent(node);\n\t\tif (parent === undefined) {\n\t\t\treturn rootFieldKey;\n\t\t}\n\n\t\t// The flex-domain strictly operates in terms of \"stored keys\".\n\t\t// To find the associated developer-facing \"view key\", we need to look up the field associated with\n\t\t// the stored key from the flex-domain, and get view key its simple-domain counterpart was created with.\n\t\tconst storedKey = getStoredKey(node);\n\t\tconst parentSchema = treeNodeApi.schema(parent);\n\t\tconst viewKey = getViewKeyFromStoredKey(parentSchema, storedKey);\n\t\treturn viewKey;\n\t},\n\ton<K extends keyof TreeChangeEvents>(\n\t\tnode: TreeNode,\n\t\teventName: K,\n\t\tlistener: TreeChangeEvents[K],\n\t): Off {\n\t\treturn getKernel(node).on(eventName, listener);\n\t},\n\tstatus(node: TreeNode): TreeStatus {\n\t\treturn getKernel(node).getStatus();\n\t},\n\tis<TSchema extends ImplicitAllowedTypes>(\n\t\tvalue: unknown,\n\t\tschema: TSchema,\n\t): value is TreeNodeFromImplicitAllowedTypes<TSchema> {\n\t\tconst actualSchema = tryGetSchema(value);\n\t\tif (actualSchema === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\tif (isReadonlyArray<LazyItem<TreeNodeSchema>>(schema)) {\n\t\t\tfor (const singleSchema of schema) {\n\t\t\t\tconst testSchema = isLazy(singleSchema) ? singleSchema() : singleSchema;\n\t\t\t\tif (testSchema === actualSchema) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} else {\n\t\t\treturn (schema as TreeNodeSchema) === actualSchema;\n\t\t}\n\t},\n\tschema<T extends TreeNode | TreeLeafValue>(\n\t\tnode: T,\n\t): TreeNodeSchema<string, NodeKind, unknown, T> {\n\t\treturn tryGetSchema(node) ?? fail(\"Not a tree node\");\n\t},\n\tshortId(node: TreeNode): number | string | undefined {\n\t\tconst flexNode = getFlexNode(node);\n\t\tconst flexSchema = flexNode.schema;\n\t\tconst identifierFieldKeys =\n\t\t\tflexSchema instanceof FlexObjectNodeSchema ? flexSchema.identifierFieldKeys : [];\n\n\t\tswitch (identifierFieldKeys.length) {\n\t\t\tcase 0:\n\t\t\t\treturn undefined;\n\t\t\tcase 1: {\n\t\t\t\tconst identifier = flexNode.tryGetField(identifierFieldKeys[0])?.boxedAt(0);\n\t\t\t\tassert(identifier !== undefined, 0x927 /* The identifier must exist */);\n\t\t\t\tconst identifierValue = identifier.value as string;\n\t\t\t\tconst localNodeKey =\n\t\t\t\t\tidentifier.context.nodeKeyManager.tryLocalizeNodeKey(identifierValue);\n\t\t\t\treturn localNodeKey !== undefined ? extractFromOpaque(localNodeKey) : identifierValue;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.\",\n\t\t\t\t);\n\t\t}\n\t},\n};\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode} or a {@link TreeLeafValue}.\n * Returns undefined for other values.\n */\nexport function tryGetSchema<T>(\n\tvalue: T,\n): undefined | TreeNodeSchema<string, NodeKind, unknown, T> {\n\ttype TOut = TreeNodeSchema<string, NodeKind, unknown, T>;\n\tswitch (typeof value) {\n\t\tcase \"string\":\n\t\t\treturn stringSchema as TOut;\n\t\tcase \"number\":\n\t\t\treturn numberSchema as TOut;\n\t\tcase \"boolean\":\n\t\t\treturn booleanSchema as TOut;\n\t\tcase \"object\": {\n\t\t\tif (isTreeNode(value)) {\n\t\t\t\t// This case could be optimized, for example by placing the simple schema in a symbol on tree nodes.\n\t\t\t\treturn tryGetSimpleNodeSchema(getFlexNode(value).schema) as TOut;\n\t\t\t}\n\t\t\tif (value === null) {\n\t\t\t\treturn nullSchema as TOut;\n\t\t\t}\n\t\t\tif (isFluidHandle(value)) {\n\t\t\t\treturn handleSchema as TOut;\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Gets the stored key with which the provided node is associated in the parent.\n */\nfunction getStoredKey(node: TreeNode): string | number {\n\t// Note: the flex domain strictly works with \"stored keys\", and knows nothing about the developer-facing\n\t// \"view keys\".\n\tconst parentField = getFlexNode(node).parentField;\n\tif (parentField.parent.schema.kind.multiplicity === Multiplicity.Sequence) {\n\t\t// The parent of `node` is an array node\n\t\treturn parentField.index;\n\t}\n\n\t// The parent of `node` is an object, a map, or undefined (and therefore `node` is a root/detached node).\n\treturn parentField.parent.key;\n}\n\n/**\n * Given a node schema, gets the view key corresponding with the provided {@link FieldProps.key | stored key}.\n */\nfunction getViewKeyFromStoredKey(\n\tschema: TreeNodeSchema,\n\tstoredKey: string | number,\n): string | number {\n\t// Only object nodes have the concept of a \"stored key\", differentiated from the developer-facing \"view key\".\n\t// For any other kind of node, the stored key and the view key are the same.\n\tif (schema.kind !== NodeKind.Object) {\n\t\treturn storedKey;\n\t}\n\n\tconst fields = schema.info as Record<string, ImplicitFieldSchema>;\n\n\t// Invariants:\n\t// - The set of all view keys under an object must be unique.\n\t// - The set of all stored keys (including those implicitly created from view keys) must be unique.\n\t// To find the view key associated with the provided stored key, first check for any stored key matches (which are optionally populated).\n\t// If we don't find any, then search for a matching view key.\n\tfor (const [viewKey, fieldSchema] of Object.entries(fields)) {\n\t\tif (fieldSchema instanceof FieldSchema && fieldSchema.props?.key === storedKey) {\n\t\t\treturn viewKey;\n\t\t}\n\t}\n\n\tif (fields[storedKey] === undefined) {\n\t\tfail(\"Existing stored key should always map to a view key\");\n\t}\n\n\treturn storedKey;\n}\n"]}
@@ -0,0 +1,26 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { type Listenable, type Off } from "../events/index.js";
6
+ import type { TreeChangeEvents, TreeNode } from "./types.js";
7
+ import type { AnchorNode } from "../core/index.js";
8
+ import { TreeStatus } from "../feature-libraries/index.js";
9
+ /**
10
+ * Contains state and an internal API for managing {@link TreeNode}s.
11
+ * @remarks All {@link TreeNode}s have an associated kernel object.
12
+ * The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.
13
+ * When hydration occurs, the kernel is notified via the {@link TreeNodeKernel.hydrate | hydrate} method.
14
+ */
15
+ export declare class TreeNodeKernel implements Listenable<TreeChangeEvents> {
16
+ #private;
17
+ readonly node: TreeNode;
18
+ constructor(node: TreeNode);
19
+ hydrate(anchorNode: AnchorNode): void;
20
+ dehydrate(): void;
21
+ isHydrated(): boolean;
22
+ getStatus(): TreeStatus;
23
+ on<K extends keyof TreeChangeEvents>(eventName: K, listener: TreeChangeEvents[K]): Off;
24
+ dispose(): void;
25
+ }
26
+ //# sourceMappingURL=treeNodeKernel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treeNodeKernel.d.ts","sourceRoot":"","sources":["../../src/simple-tree/treeNodeKernel.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAIN,UAAU,EAEV,MAAM,+BAA+B,CAAC;AAEvC;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,UAAU,CAAC,gBAAgB,CAAC;;aAO/B,IAAI,EAAE,QAAQ;gBAAd,IAAI,EAAE,QAAQ;IAE1C,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAqBrC,SAAS,IAAI,IAAI;IAKjB,UAAU,IAAI,OAAO;IAIrB,SAAS,IAAI,UAAU;IAiBvB,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACzC,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,GAAG;IAIC,OAAO,IAAI,IAAI;CAItB"}