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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. package/api-extractor/api-extractor-lint-beta.cjs.json +5 -0
  2. package/api-extractor/api-extractor-lint-beta.esm.json +5 -0
  3. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  4. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  5. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  6. package/api-report/tree.alpha.api.md +2 -13
  7. package/api-report/tree.beta.api.md +2 -13
  8. package/api-report/tree.public.api.md +2 -13
  9. package/dist/beta.d.ts +0 -1
  10. package/dist/codec/codec.js +0 -1
  11. package/dist/codec/codec.js.map +1 -1
  12. package/dist/codec/discriminatedUnions.js +0 -1
  13. package/dist/codec/discriminatedUnions.js.map +1 -1
  14. package/dist/core/change-family/editBuilder.js +0 -2
  15. package/dist/core/change-family/editBuilder.js.map +1 -1
  16. package/dist/core/rebase/revisionTagCodec.js +0 -2
  17. package/dist/core/rebase/revisionTagCodec.js.map +1 -1
  18. package/dist/core/schema-stored/schema.js +0 -4
  19. package/dist/core/schema-stored/schema.js.map +1 -1
  20. package/dist/core/schema-stored/storedSchemaRepository.js +1 -3
  21. package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
  22. package/dist/core/schema-view/view.js +0 -2
  23. package/dist/core/schema-view/view.js.map +1 -1
  24. package/dist/core/tree/anchorSet.js +46 -51
  25. package/dist/core/tree/anchorSet.js.map +1 -1
  26. package/dist/core/tree/detachedFieldIndex.js +2 -8
  27. package/dist/core/tree/detachedFieldIndex.js.map +1 -1
  28. package/dist/core/tree/detachedFieldIndexCodec.js +0 -3
  29. package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
  30. package/dist/core/tree/sparseTree.js +11 -15
  31. package/dist/core/tree/sparseTree.js.map +1 -1
  32. package/dist/domains/schemaBuilder.js +70 -70
  33. package/dist/domains/schemaBuilder.js.map +1 -1
  34. package/dist/events/events.js +1 -2
  35. package/dist/events/events.js.map +1 -1
  36. package/dist/feature-libraries/chunked-forest/basicChunk.js +1 -14
  37. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  38. package/dist/feature-libraries/chunked-forest/chunkTree.js +6 -13
  39. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  40. package/dist/feature-libraries/chunked-forest/chunkedForest.js +2 -9
  41. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  42. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js +3 -1
  43. package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
  44. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -3
  45. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  46. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +6 -11
  47. package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  48. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +3 -3
  49. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  50. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +2 -5
  51. package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  52. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +0 -1
  53. package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  54. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -1
  55. package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  56. package/dist/feature-libraries/chunked-forest/codec/codecs.js +4 -1
  57. package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  58. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +13 -25
  59. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  60. package/dist/feature-libraries/chunked-forest/codec/nodeShape.d.ts.map +1 -1
  61. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js +5 -8
  62. package/dist/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  63. package/dist/feature-libraries/chunked-forest/sequenceChunk.js +0 -1
  64. package/dist/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
  65. package/dist/feature-libraries/chunked-forest/uniformChunk.js +5 -40
  66. package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  67. package/dist/feature-libraries/default-schema/defaultEditBuilder.js +0 -2
  68. package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  69. package/dist/feature-libraries/detachedFieldIndexSummarizer.js +1 -2
  70. package/dist/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
  71. package/dist/feature-libraries/editableTreeBinder.js +12 -13
  72. package/dist/feature-libraries/editableTreeBinder.js.map +1 -1
  73. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +11 -12
  74. package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  75. package/dist/feature-libraries/flex-tree/context.js +3 -7
  76. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  77. package/dist/feature-libraries/flex-tree/lazyEntity.js +22 -13
  78. package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  79. package/dist/feature-libraries/flex-tree/lazyField.js +0 -6
  80. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  81. package/dist/feature-libraries/flex-tree/lazyNode.js +17 -10
  82. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  83. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  84. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  85. package/dist/feature-libraries/index.d.ts +1 -1
  86. package/dist/feature-libraries/index.d.ts.map +1 -1
  87. package/dist/feature-libraries/index.js +2 -3
  88. package/dist/feature-libraries/index.js.map +1 -1
  89. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +7 -7
  90. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  91. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js +6 -6
  92. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  93. package/dist/feature-libraries/modular-schema/fieldKind.js +0 -2
  94. package/dist/feature-libraries/modular-schema/fieldKind.js.map +1 -1
  95. package/dist/feature-libraries/modular-schema/fieldKindWithEditor.js +0 -3
  96. package/dist/feature-libraries/modular-schema/fieldKindWithEditor.js.map +1 -1
  97. package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
  98. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  99. package/dist/feature-libraries/modular-schema/index.js +2 -2
  100. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  101. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +2 -0
  102. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  103. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +2 -0
  104. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  105. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +39 -24
  106. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  107. package/dist/feature-libraries/node-key/mockNodeKeyManager.js +4 -2
  108. package/dist/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  109. package/dist/feature-libraries/node-key/nodeKeyIndex.js +0 -3
  110. package/dist/feature-libraries/node-key/nodeKeyIndex.js.map +1 -1
  111. package/dist/feature-libraries/object-forest/objectForest.js +28 -23
  112. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  113. package/dist/feature-libraries/optional-field/optionalField.js +5 -3
  114. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  115. package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -5
  116. package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  117. package/dist/feature-libraries/schemaBuilderBase.js +3 -14
  118. package/dist/feature-libraries/schemaBuilderBase.js.map +1 -1
  119. package/dist/feature-libraries/sequence-field/compose.js +0 -6
  120. package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
  121. package/dist/feature-libraries/sequence-field/markListFactory.js +4 -3
  122. package/dist/feature-libraries/sequence-field/markListFactory.js.map +1 -1
  123. package/dist/feature-libraries/sequence-field/markQueue.js +2 -4
  124. package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
  125. package/dist/feature-libraries/sequence-field/rebase.d.ts +2 -2
  126. package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  127. package/dist/feature-libraries/sequence-field/rebase.js +20 -20
  128. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  129. package/dist/feature-libraries/treeCursorUtils.js +9 -13
  130. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  131. package/dist/feature-libraries/typed-schema/typedTreeSchema.js +4 -23
  132. package/dist/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  133. package/dist/feature-libraries/typed-schema/view.js +0 -7
  134. package/dist/feature-libraries/typed-schema/view.js.map +1 -1
  135. package/dist/index.d.ts +1 -1
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +1 -2
  138. package/dist/index.js.map +1 -1
  139. package/dist/packageVersion.d.ts +1 -1
  140. package/dist/packageVersion.js +1 -1
  141. package/dist/packageVersion.js.map +1 -1
  142. package/dist/public.d.ts +0 -1
  143. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  144. package/dist/shared-tree/schematizingTreeView.js +10 -27
  145. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  146. package/dist/shared-tree/sharedTree.d.ts +4 -0
  147. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  148. package/dist/shared-tree/sharedTree.js +13 -10
  149. package/dist/shared-tree/sharedTree.js.map +1 -1
  150. package/dist/shared-tree/sharedTreeChangeEnricher.js +11 -14
  151. package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  152. package/dist/shared-tree/sharedTreeChangeFamily.js +3 -5
  153. package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  154. package/dist/shared-tree/sharedTreeEditBuilder.js +0 -2
  155. package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  156. package/dist/shared-tree/treeCheckout.js +11 -22
  157. package/dist/shared-tree/treeCheckout.js.map +1 -1
  158. package/dist/shared-tree/treeView.js +0 -6
  159. package/dist/shared-tree/treeView.js.map +1 -1
  160. package/dist/shared-tree-core/branch.d.ts +18 -0
  161. package/dist/shared-tree-core/branch.d.ts.map +1 -1
  162. package/dist/shared-tree-core/branch.js +28 -31
  163. package/dist/shared-tree-core/branch.js.map +1 -1
  164. package/dist/shared-tree-core/branchCommitEnricher.d.ts +4 -2
  165. package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  166. package/dist/shared-tree-core/branchCommitEnricher.js +19 -15
  167. package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
  168. package/dist/shared-tree-core/defaultResubmitMachine.js +19 -21
  169. package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  170. package/dist/shared-tree-core/editManager.js +37 -53
  171. package/dist/shared-tree-core/editManager.js.map +1 -1
  172. package/dist/shared-tree-core/editManagerSummarizer.js +1 -5
  173. package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
  174. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  175. package/dist/shared-tree-core/sharedTreeCore.js +16 -24
  176. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  177. package/dist/shared-tree-core/transactionEnricher.d.ts +11 -1
  178. package/dist/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  179. package/dist/shared-tree-core/transactionEnricher.js +25 -4
  180. package/dist/shared-tree-core/transactionEnricher.js.map +1 -1
  181. package/dist/shared-tree-core/transactionStack.js +3 -1
  182. package/dist/shared-tree-core/transactionStack.js.map +1 -1
  183. package/dist/simple-tree/arrayNode.js +34 -26
  184. package/dist/simple-tree/arrayNode.js.map +1 -1
  185. package/dist/simple-tree/leafNodeSchema.js +2 -4
  186. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  187. package/dist/simple-tree/mapNode.js +5 -5
  188. package/dist/simple-tree/mapNode.js.map +1 -1
  189. package/dist/simple-tree/objectNode.js +6 -6
  190. package/dist/simple-tree/objectNode.js.map +1 -1
  191. package/dist/simple-tree/schemaFactory.d.ts +18 -5
  192. package/dist/simple-tree/schemaFactory.d.ts.map +1 -1
  193. package/dist/simple-tree/schemaFactory.js +65 -53
  194. package/dist/simple-tree/schemaFactory.js.map +1 -1
  195. package/dist/simple-tree/schemaTypes.js +3 -12
  196. package/dist/simple-tree/schemaTypes.js.map +1 -1
  197. package/dist/simple-tree/tree.d.ts +1 -22
  198. package/dist/simple-tree/tree.d.ts.map +1 -1
  199. package/dist/simple-tree/tree.js +0 -21
  200. package/dist/simple-tree/tree.js.map +1 -1
  201. package/dist/simple-tree/treeNodeApi.d.ts +13 -4
  202. package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
  203. package/dist/simple-tree/treeNodeApi.js +8 -3
  204. package/dist/simple-tree/treeNodeApi.js.map +1 -1
  205. package/dist/simple-tree/types.d.ts +26 -6
  206. package/dist/simple-tree/types.d.ts.map +1 -1
  207. package/dist/simple-tree/types.js +79 -54
  208. package/dist/simple-tree/types.js.map +1 -1
  209. package/dist/treeFactory.js +10 -9
  210. package/dist/treeFactory.js.map +1 -1
  211. package/dist/util/brand.js +0 -1
  212. package/dist/util/brand.js.map +1 -1
  213. package/dist/util/nestedMap.js +4 -2
  214. package/dist/util/nestedMap.js.map +1 -1
  215. package/dist/util/offsetList.js +4 -2
  216. package/dist/util/offsetList.js.map +1 -1
  217. package/dist/util/referenceCounting.js +0 -1
  218. package/dist/util/referenceCounting.js.map +1 -1
  219. package/dist/util/stackyIterator.js +2 -3
  220. package/dist/util/stackyIterator.js.map +1 -1
  221. package/lib/beta.d.ts +0 -1
  222. package/lib/codec/codec.js +0 -1
  223. package/lib/codec/codec.js.map +1 -1
  224. package/lib/codec/discriminatedUnions.js +0 -1
  225. package/lib/codec/discriminatedUnions.js.map +1 -1
  226. package/lib/core/change-family/editBuilder.js +0 -2
  227. package/lib/core/change-family/editBuilder.js.map +1 -1
  228. package/lib/core/rebase/revisionTagCodec.js +0 -2
  229. package/lib/core/rebase/revisionTagCodec.js.map +1 -1
  230. package/lib/core/schema-stored/schema.js +0 -4
  231. package/lib/core/schema-stored/schema.js.map +1 -1
  232. package/lib/core/schema-stored/storedSchemaRepository.js +1 -3
  233. package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
  234. package/lib/core/schema-view/view.js +0 -2
  235. package/lib/core/schema-view/view.js.map +1 -1
  236. package/lib/core/tree/anchorSet.js +46 -51
  237. package/lib/core/tree/anchorSet.js.map +1 -1
  238. package/lib/core/tree/detachedFieldIndex.js +2 -8
  239. package/lib/core/tree/detachedFieldIndex.js.map +1 -1
  240. package/lib/core/tree/detachedFieldIndexCodec.js +0 -3
  241. package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
  242. package/lib/core/tree/sparseTree.js +11 -15
  243. package/lib/core/tree/sparseTree.js.map +1 -1
  244. package/lib/domains/schemaBuilder.js +70 -70
  245. package/lib/domains/schemaBuilder.js.map +1 -1
  246. package/lib/events/events.js +1 -2
  247. package/lib/events/events.js.map +1 -1
  248. package/lib/feature-libraries/chunked-forest/basicChunk.js +1 -14
  249. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  250. package/lib/feature-libraries/chunked-forest/chunkTree.js +6 -13
  251. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  252. package/lib/feature-libraries/chunked-forest/chunkedForest.js +2 -9
  253. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  254. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js +3 -1
  255. package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
  256. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -3
  257. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
  258. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +6 -11
  259. package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
  260. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +3 -3
  261. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
  262. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +2 -5
  263. package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
  264. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +0 -1
  265. package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
  266. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -1
  267. package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
  268. package/lib/feature-libraries/chunked-forest/codec/codecs.js +4 -1
  269. package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
  270. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +13 -25
  271. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  272. package/lib/feature-libraries/chunked-forest/codec/nodeShape.d.ts.map +1 -1
  273. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js +5 -8
  274. package/lib/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
  275. package/lib/feature-libraries/chunked-forest/sequenceChunk.js +0 -1
  276. package/lib/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
  277. package/lib/feature-libraries/chunked-forest/uniformChunk.js +5 -40
  278. package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
  279. package/lib/feature-libraries/default-schema/defaultEditBuilder.js +0 -2
  280. package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
  281. package/lib/feature-libraries/detachedFieldIndexSummarizer.js +1 -2
  282. package/lib/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
  283. package/lib/feature-libraries/editableTreeBinder.js +12 -13
  284. package/lib/feature-libraries/editableTreeBinder.js.map +1 -1
  285. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +11 -12
  286. package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
  287. package/lib/feature-libraries/flex-tree/context.js +3 -7
  288. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  289. package/lib/feature-libraries/flex-tree/lazyEntity.js +22 -13
  290. package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  291. package/lib/feature-libraries/flex-tree/lazyField.js +0 -6
  292. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  293. package/lib/feature-libraries/flex-tree/lazyNode.js +17 -10
  294. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  295. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  296. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  297. package/lib/feature-libraries/index.d.ts +1 -1
  298. package/lib/feature-libraries/index.d.ts.map +1 -1
  299. package/lib/feature-libraries/index.js +1 -1
  300. package/lib/feature-libraries/index.js.map +1 -1
  301. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +7 -7
  302. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  303. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js +5 -5
  304. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  305. package/lib/feature-libraries/modular-schema/fieldKind.js +0 -2
  306. package/lib/feature-libraries/modular-schema/fieldKind.js.map +1 -1
  307. package/lib/feature-libraries/modular-schema/fieldKindWithEditor.js +0 -3
  308. package/lib/feature-libraries/modular-schema/fieldKindWithEditor.js.map +1 -1
  309. package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
  310. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  311. package/lib/feature-libraries/modular-schema/index.js +1 -1
  312. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  313. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +2 -0
  314. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  315. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +2 -0
  316. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  317. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +40 -25
  318. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  319. package/lib/feature-libraries/node-key/mockNodeKeyManager.js +4 -2
  320. package/lib/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
  321. package/lib/feature-libraries/node-key/nodeKeyIndex.js +0 -3
  322. package/lib/feature-libraries/node-key/nodeKeyIndex.js.map +1 -1
  323. package/lib/feature-libraries/object-forest/objectForest.js +28 -23
  324. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  325. package/lib/feature-libraries/optional-field/optionalField.js +6 -4
  326. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  327. package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -5
  328. package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
  329. package/lib/feature-libraries/schemaBuilderBase.js +3 -14
  330. package/lib/feature-libraries/schemaBuilderBase.js.map +1 -1
  331. package/lib/feature-libraries/sequence-field/compose.js +0 -6
  332. package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
  333. package/lib/feature-libraries/sequence-field/markListFactory.js +4 -3
  334. package/lib/feature-libraries/sequence-field/markListFactory.js.map +1 -1
  335. package/lib/feature-libraries/sequence-field/markQueue.js +2 -4
  336. package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
  337. package/lib/feature-libraries/sequence-field/rebase.d.ts +2 -2
  338. package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
  339. package/lib/feature-libraries/sequence-field/rebase.js +21 -21
  340. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  341. package/lib/feature-libraries/treeCursorUtils.js +9 -13
  342. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  343. package/lib/feature-libraries/typed-schema/typedTreeSchema.js +4 -23
  344. package/lib/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
  345. package/lib/feature-libraries/typed-schema/view.js +0 -7
  346. package/lib/feature-libraries/typed-schema/view.js.map +1 -1
  347. package/lib/index.d.ts +1 -1
  348. package/lib/index.d.ts.map +1 -1
  349. package/lib/index.js +1 -1
  350. package/lib/index.js.map +1 -1
  351. package/lib/packageVersion.d.ts +1 -1
  352. package/lib/packageVersion.js +1 -1
  353. package/lib/packageVersion.js.map +1 -1
  354. package/lib/public.d.ts +0 -1
  355. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  356. package/lib/shared-tree/schematizingTreeView.js +10 -27
  357. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  358. package/lib/shared-tree/sharedTree.d.ts +4 -0
  359. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  360. package/lib/shared-tree/sharedTree.js +13 -10
  361. package/lib/shared-tree/sharedTree.js.map +1 -1
  362. package/lib/shared-tree/sharedTreeChangeEnricher.js +11 -14
  363. package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
  364. package/lib/shared-tree/sharedTreeChangeFamily.js +3 -5
  365. package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
  366. package/lib/shared-tree/sharedTreeEditBuilder.js +0 -2
  367. package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
  368. package/lib/shared-tree/treeCheckout.js +11 -22
  369. package/lib/shared-tree/treeCheckout.js.map +1 -1
  370. package/lib/shared-tree/treeView.js +0 -6
  371. package/lib/shared-tree/treeView.js.map +1 -1
  372. package/lib/shared-tree-core/branch.d.ts +18 -0
  373. package/lib/shared-tree-core/branch.d.ts.map +1 -1
  374. package/lib/shared-tree-core/branch.js +28 -31
  375. package/lib/shared-tree-core/branch.js.map +1 -1
  376. package/lib/shared-tree-core/branchCommitEnricher.d.ts +4 -2
  377. package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
  378. package/lib/shared-tree-core/branchCommitEnricher.js +19 -15
  379. package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
  380. package/lib/shared-tree-core/defaultResubmitMachine.js +19 -21
  381. package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
  382. package/lib/shared-tree-core/editManager.js +37 -53
  383. package/lib/shared-tree-core/editManager.js.map +1 -1
  384. package/lib/shared-tree-core/editManagerSummarizer.js +1 -5
  385. package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
  386. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  387. package/lib/shared-tree-core/sharedTreeCore.js +16 -24
  388. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  389. package/lib/shared-tree-core/transactionEnricher.d.ts +11 -1
  390. package/lib/shared-tree-core/transactionEnricher.d.ts.map +1 -1
  391. package/lib/shared-tree-core/transactionEnricher.js +25 -4
  392. package/lib/shared-tree-core/transactionEnricher.js.map +1 -1
  393. package/lib/shared-tree-core/transactionStack.js +3 -1
  394. package/lib/shared-tree-core/transactionStack.js.map +1 -1
  395. package/lib/simple-tree/arrayNode.js +34 -26
  396. package/lib/simple-tree/arrayNode.js.map +1 -1
  397. package/lib/simple-tree/leafNodeSchema.js +2 -4
  398. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  399. package/lib/simple-tree/mapNode.js +5 -5
  400. package/lib/simple-tree/mapNode.js.map +1 -1
  401. package/lib/simple-tree/objectNode.js +6 -6
  402. package/lib/simple-tree/objectNode.js.map +1 -1
  403. package/lib/simple-tree/schemaFactory.d.ts +18 -5
  404. package/lib/simple-tree/schemaFactory.d.ts.map +1 -1
  405. package/lib/simple-tree/schemaFactory.js +65 -53
  406. package/lib/simple-tree/schemaFactory.js.map +1 -1
  407. package/lib/simple-tree/schemaTypes.js +3 -12
  408. package/lib/simple-tree/schemaTypes.js.map +1 -1
  409. package/lib/simple-tree/tree.d.ts +1 -22
  410. package/lib/simple-tree/tree.d.ts.map +1 -1
  411. package/lib/simple-tree/tree.js +0 -21
  412. package/lib/simple-tree/tree.js.map +1 -1
  413. package/lib/simple-tree/treeNodeApi.d.ts +13 -4
  414. package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
  415. package/lib/simple-tree/treeNodeApi.js +8 -3
  416. package/lib/simple-tree/treeNodeApi.js.map +1 -1
  417. package/lib/simple-tree/types.d.ts +26 -6
  418. package/lib/simple-tree/types.d.ts.map +1 -1
  419. package/lib/simple-tree/types.js +78 -54
  420. package/lib/simple-tree/types.js.map +1 -1
  421. package/lib/treeFactory.js +10 -9
  422. package/lib/treeFactory.js.map +1 -1
  423. package/lib/util/brand.js +0 -1
  424. package/lib/util/brand.js.map +1 -1
  425. package/lib/util/nestedMap.js +4 -2
  426. package/lib/util/nestedMap.js.map +1 -1
  427. package/lib/util/offsetList.js +4 -2
  428. package/lib/util/offsetList.js.map +1 -1
  429. package/lib/util/referenceCounting.js +0 -1
  430. package/lib/util/referenceCounting.js.map +1 -1
  431. package/lib/util/stackyIterator.js +2 -3
  432. package/lib/util/stackyIterator.js.map +1 -1
  433. package/package.json +27 -24
  434. package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +22 -6
  435. package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +2 -2
  436. package/src/feature-libraries/chunked-forest/codec/codecs.ts +6 -2
  437. package/src/feature-libraries/chunked-forest/codec/nodeShape.ts +8 -3
  438. package/src/feature-libraries/index.ts +0 -1
  439. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +6 -7
  440. package/src/feature-libraries/modular-schema/index.ts +1 -1
  441. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +2 -0
  442. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +55 -23
  443. package/src/feature-libraries/optional-field/optionalField.ts +3 -3
  444. package/src/feature-libraries/sequence-field/rebase.ts +15 -33
  445. package/src/index.ts +0 -1
  446. package/src/packageVersion.ts +1 -1
  447. package/src/shared-tree/schematizingTreeView.ts +0 -2
  448. package/src/shared-tree/sharedTree.ts +8 -1
  449. package/src/shared-tree-core/branch.ts +24 -0
  450. package/src/shared-tree-core/branchCommitEnricher.ts +15 -6
  451. package/src/shared-tree-core/sharedTreeCore.ts +9 -0
  452. package/src/shared-tree-core/transactionEnricher.ts +27 -1
  453. package/src/simple-tree/arrayNode.ts +17 -17
  454. package/src/simple-tree/schemaFactory.ts +18 -5
  455. package/src/simple-tree/tree.ts +1 -26
  456. package/src/simple-tree/treeNodeApi.ts +25 -7
  457. package/src/simple-tree/types.ts +57 -9
  458. package/tsdoc.json +4 -0
@@ -1 +1 @@
1
- {"version":3,"file":"schemaTypes.js","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,kEAA2D;AAC3D,uEAAsE;AAEtE,4DAKuC;AACvC,+CAA4E;AAmH5E;;;GAGG;AACH,IAAY,SAmBX;AAnBD,WAAY,SAAS;IACpB;;;;OAIG;IACH,iDAAQ,CAAA;IACR;;;;OAIG;IACH,iDAAQ,CAAA;IACR;;;;OAIG;IACH,qDAAU,CAAA;AACX,CAAC,EAnBW,SAAS,yBAAT,SAAS,QAmBpB;AAED;;;GAGG;AACH,IAAY,QAmBX;AAnBD,WAAY,QAAQ;IACnB;;OAEG;IACH,qCAAG,CAAA;IACH;;OAEG;IACH,yCAAK,CAAA;IACL;;;;OAIG;IACH,2CAAM,CAAA;IACN;;OAEG;IACH,uCAAI,CAAA;AACL,CAAC,EAnBW,QAAQ,wBAAR,QAAQ,QAmBnB;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAAC,OAAe,EAAE,WAAgC;IAC7E,OAAO,IAAA,gBAAK,EAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,CAAC;AAC5D,CAAC;AAFD,oCAEC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,WAAgC;IACpE,OAAO,WAAW,YAAY,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC;AAFD,oDAEC;AA+ED;;GAEG;AACH,SAAgB,UAAU,CAAC,aAA4B;IACtD,OAAO,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;AACnC,CAAC;AAFD,gCAEC;AAUD,SAAgB,oBAAoB,CAAC,KAAsB;IAC1D,OAAO,KAAiC,CAAC;AAC1C,CAAC;AAFD,oDAEC;AAED,SAAgB,kBAAkB,CAAC,KAAoB;IACtD,OAAO,KAAmC,CAAC;AAC5C,CAAC;AAFD,gDAEC;AAcD;;;;;;;;;;GAUG;AACH,MAAa,WAAW;IAmCN;IAIA;IAIA;IAvCjB;QACC,yBAAiB,GAAG,CAInB,IAAW,EACX,YAAoB,EACpB,KAAkB,EACjB,EAAE,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IACD;;;OAGG;IACO,UAAU,CAAe;IAElB,SAAS,CAAoC;IAE9D;;;OAGG;IACH,IAAW,cAAc;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED;IACC;;;OAGG;IACa,IAAU;IAC1B;;OAEG;IACa,YAAmB;IACnC;;OAEG;IACa,KAAkB;QARlB,SAAI,GAAJ,IAAI,CAAM;QAIV,iBAAY,GAAZ,YAAY,CAAO;QAInB,UAAK,GAAL,KAAK,CAAa;QAElC,IAAI,CAAC,SAAS,GAAG,IAAI,eAAI,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3E,CAAC;CACD;AA/CD,kCA+CC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,MAA2B;IAC/D,OAAO,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,yBAAiB,EAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC/F,CAAC;AAFD,oDAEC;AACD;;;;;;GAMG;AACH,SAAgB,qBAAqB,CAAC,KAA2B;IAChE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,IAAI,IAAA,0BAAe,EAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC9B,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;SAAM,CAAC;QACP,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAVD,sDAUC;AAED,SAAS,kBAAkB,CAAC,KAA+B;IAC1D,MAAM,eAAe,GAAG,IAAA,iBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACxD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAU,CACnB,iHAAiH,CACjH,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACxB,CAAC;AA0HD;;;;;;;;;;;;GAYG;AACU,QAAA,IAAI,GAAkB,MAAM,CAAC,eAAe,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedType, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { Lazy } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype InternalFlexListTypes,\n\ttype LazyItem,\n\ttype NodeKeyManager,\n\tisLazy,\n} from \"../feature-libraries/index.js\";\nimport { type MakeNominal, brand, isReadonlyArray } from \"../util/index.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport type { FieldKey } from \"../core/index.js\";\nimport type { InsertableContent } from \"./proxies.js\";\n\n/**\n * Schema for a tree node.\n * @typeParam Name - The full (including scope) name/identifier for the schema.\n * @typeParam Kind - Which kind of node this schema is for.\n * @typeParam TNode - API for nodes that use this schema.\n * @typeParam TBuild - Data which can be used to construct an {@link Unhydrated} node of this type.\n * @typeParam Info - Data used when defining this schema.\n * @remarks\n * Captures the schema both as runtime data and compile time type information.\n * @public\n */\nexport type TreeNodeSchema<\n\tName extends string = string,\n\tKind extends NodeKind = NodeKind,\n\tTNode = unknown,\n\tTBuild = never,\n\tImplicitlyConstructable extends boolean = boolean,\n\tInfo = unknown,\n> =\n\t| TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>\n\t| TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>;\n\n/**\n * Schema which is not a class.\n * @remarks\n * This is used for schema which cannot have their instances constructed using constructors, like leaf schema.\n * @privateRemarks\n * Non-class based schema can have issues with recursive types due to https://github.com/microsoft/TypeScript/issues/55832.\n * @public\n */\nexport interface TreeNodeSchemaNonClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\tcreate(data: TInsertable): TNode;\n}\n\n/**\n * Tree node schema which is implemented using a class.\n * @remarks\n * Instances of this class are nodes in the tree.\n * This is also a constructor so that it can be subclassed.\n *\n * Using classes in this way allows introducing a named type and a named value at the same time, helping keep the runtime and compile time information together and easy to refer to un a uniform way.\n * Additionally, this works around https://github.com/microsoft/TypeScript/issues/55832 which causes similar patterns with less explicit types to infer \"any\" in the d.ts file.\n * @public\n */\nexport interface TreeNodeSchemaClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\t/**\n\t * Constructs an {@link Unhydrated} node with this schema.\n\t * @remarks\n\t * This constructor is also used internally to construct hydrated nodes with a different parameter type.\n\t * Therefor overriding this constructor is not type-safe and is not supported.\n\t * @sealed\n\t */\n\tnew (data: TInsertable | InternalTreeNode): Unhydrated<TNode>;\n}\n\n/**\n * Data common to all tree node schema.\n * @public\n */\nexport interface TreeNodeSchemaCore<\n\tout Name extends string,\n\tout Kind extends NodeKind,\n\tout ImplicitlyConstructable extends boolean,\n\tout Info = unknown,\n> {\n\treadonly identifier: Name;\n\treadonly kind: Kind;\n\n\t/**\n\t * Data used to define this schema.\n\t *\n\t * @remarks\n\t * The format depends on the kind of node it is for.\n\t * For example, the \"object\" node kind could store the field schema here.\n\t */\n\treadonly info: Info;\n\n\t/**\n\t * When constructing insertable content,\n\t * data that could be passed to the node's constructor can be used instead of an {@link Unhydrated} node\n\t * iff implicitlyConstructable is true.\n\t * @privateRemarks\n\t * Currently the logic for traversing insertable content,\n\t * both to build trees and to hydrate them does not defer to the schema classes to handle the policy,\n\t * so if their constructors differ from what is supported, some cases will not work.\n\t * Setting this to false adjusts the insertable types to disallow cases which could be impacted by these inconsistencies.\n\t */\n\treadonly implicitlyConstructable: ImplicitlyConstructable;\n}\n\n/**\n * Types for use in fields.\n * @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Kind of a field on a node.\n * @public\n */\nexport enum FieldKind {\n\t/**\n\t * A field which can be empty or filled.\n\t * @remarks\n\t * Allows 0 or one child.\n\t */\n\tOptional,\n\t/**\n\t * A field which must always be filled.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tRequired,\n\t/**\n\t * A special field used for node identifiers.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tIdentifier,\n}\n\n/**\n * Kind of tree node.\n * @public\n */\nexport enum NodeKind {\n\t/**\n\t * A node which serves as a map, storing children under string keys.\n\t */\n\tMap,\n\t/**\n\t * A node which serves as an array, storing children in an ordered sequence.\n\t */\n\tArray,\n\t/**\n\t * A node which stores a heterogenous collection of children in named fields.\n\t * @remarks\n\t * Each field gets its own schema.\n\t */\n\tObject,\n\t/**\n\t * A node which stores a single leaf value.\n\t */\n\tLeaf,\n}\n\n/**\n * Maps from a view key to its corresponding {@link FieldProps.key | stored key} for the provided\n * {@link ImplicitFieldSchema | field schema}.\n *\n * @remarks\n * If an explicit stored key was specified in the schema, it will be used.\n * Otherwise, the stored key is the same as the view key.\n */\nexport function getStoredKey(viewKey: string, fieldSchema: ImplicitFieldSchema): FieldKey {\n\treturn brand(getExplicitStoredKey(fieldSchema) ?? viewKey);\n}\n\n/**\n * Gets the {@link FieldProps.key | stored key} specified by the schema, if one was explicitly specified.\n * Otherwise, returns undefined.\n */\nexport function getExplicitStoredKey(fieldSchema: ImplicitFieldSchema): string | undefined {\n\treturn fieldSchema instanceof FieldSchema ? fieldSchema.props?.key : undefined;\n}\n\n/**\n * Additional information to provide to a {@link FieldSchema}.\n *\n * @public\n */\nexport interface FieldProps {\n\t/**\n\t * The unique identifier of a field, used in the persisted form of the tree.\n\t *\n\t * @remarks\n\t * If not explicitly set via the schema, this is the same as the schema's property key.\n\t *\n\t * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.\n\t * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,\n\t * you can change the property key and specify the previous property key as the stored key.\n\t *\n\t * Notes:\n\t *\n\t * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`\n\t * will always return the property keys specified in the schema, ignoring any stored keys that differ from\n\t * the property keys.\n\t *\n\t * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys\n\t * (accounting for those implicitly derived from property keys) contains no duplicates.\n\t * This is validated at runtime.\n\t *\n\t * @example Refactoring code without breaking compatibility with existing data\n\t *\n\t * Consider some existing object schema:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \txPosition: schemaFactory.number,\n\t * \tyPosition: schemaFactory.number,\n\t * \tzPosition: schemaFactory.optional(schemaFactory.number),\n\t * });\n\t * ```\n\t *\n\t * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.\n\t *\n\t * We would like to refactor the schema to omit \"Position\" from the property keys, but application data has\n\t * already been persisted using the original property keys. To maintain compatibility with existing data,\n\t * we can refactor the schema as follows:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \tx: schemaFactory.required(schemaFactory.number, { key: \"xPosition\" }),\n\t * \ty: schemaFactory.required(schemaFactory.number, { key: \"yPosition\" }),\n\t * \tz: schemaFactory.optional(schemaFactory.number, { key: \"zPosition\" }),\n\t * });\n\t * ```\n\t *\n\t * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.\n\t *\n\t * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.\n\t */\n\treadonly key?: string;\n\t/**\n\t * A default provider used for fields which were not provided any values.\n\t * @privateRemarks\n\t * We are using an erased type here, as we want to expose this API but `InsertableContent` and `NodeKeyManager` are not public.\n\t */\n\treadonly defaultProvider?: DefaultProvider;\n}\n\n/**\n * A {@link FieldProvider} which requires additional context in order to produce its content\n */\nexport type ContextualFieldProvider = (context: NodeKeyManager) => InsertableContent | undefined;\n/**\n * A {@link FieldProvider} which can produce its content in a vacuum\n */\nexport type ConstantFieldProvider = () => InsertableContent | undefined;\n/**\n * A function which produces content for a field every time that it is called\n */\nexport type FieldProvider = ContextualFieldProvider | ConstantFieldProvider;\n/**\n * Returns true if the given {@link FieldProvider} is a {@link ConstantFieldProvider}\n */\nexport function isConstant(fieldProvider: FieldProvider): fieldProvider is ConstantFieldProvider {\n\treturn fieldProvider.length === 0;\n}\n\n/**\n * Provides a default value for a field.\n * @remarks\n * If present in a `FieldSchema`, when constructing new tree content that field can be omitted, and a default will be provided.\n * @public\n */\nexport interface DefaultProvider extends ErasedType<\"@fluidframework/tree.FieldProvider\"> {}\n\nexport function extractFieldProvider(input: DefaultProvider): FieldProvider {\n\treturn input as unknown as FieldProvider;\n}\n\nexport function getDefaultProvider(input: FieldProvider): DefaultProvider {\n\treturn input as unknown as DefaultProvider;\n}\n\n/**\n * Package internal construction API.\n */\nexport let createFieldSchema: <\n\tKind extends FieldKind = FieldKind,\n\tTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n>(\n\tkind: Kind,\n\tallowedTypes: Types,\n\tprops?: FieldProps,\n) => FieldSchema<Kind, Types>;\n\n/**\n * All policy for a specific field,\n * including functionality that does not have to be kept consistent across versions or deterministic.\n *\n * This can include policy for how to use this schema for \"view\" purposes, and well as how to expose editing APIs.\n * Use {@link SchemaFactory} to create the FieldSchema instances, for example {@link SchemaFactory.optional}.\n * @privateRemarks\n * Public access to the constructor is removed to prevent creating expressible but unsupported (or not stable) configurations.\n * {@link createFieldSchema} can be used internally to create instances.\n * @sealed @public\n */\nexport class FieldSchema<\n\tout Kind extends FieldKind = FieldKind,\n\tout Types extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n> {\n\tstatic {\n\t\tcreateFieldSchema = <\n\t\t\tKind2 extends FieldKind = FieldKind,\n\t\t\tTypes2 extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\t\t>(\n\t\t\tkind: Kind2,\n\t\t\tallowedTypes: Types2,\n\t\t\tprops?: FieldProps,\n\t\t) => new FieldSchema(kind, allowedTypes, props);\n\t}\n\t/**\n\t * This class is used with instanceof, and therefore should have nominal typing.\n\t * This field enforces that.\n\t */\n\tprotected _typeCheck?: MakeNominal;\n\n\tprivate readonly lazyTypes: Lazy<ReadonlySet<TreeNodeSchema>>;\n\n\t/**\n\t * What types of tree nodes are allowed in this field.\n\t * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.\n\t */\n\tpublic get allowedTypeSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyTypes.value;\n\t}\n\n\tprivate constructor(\n\t\t/**\n\t\t * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.\n\t\t * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.\n\t\t */\n\t\tpublic readonly kind: Kind,\n\t\t/**\n\t\t * What types of tree nodes are allowed in this field.\n\t\t */\n\t\tpublic readonly allowedTypes: Types,\n\t\t/**\n\t\t * Optional properties associated with the field.\n\t\t */\n\t\tpublic readonly props?: FieldProps,\n\t) {\n\t\tthis.lazyTypes = new Lazy(() => normalizeAllowedTypes(this.allowedTypes));\n\t}\n}\n\n/**\n * Normalizes a {@link ImplicitFieldSchema} to a {@link FieldSchema}.\n */\nexport function normalizeFieldSchema(schema: ImplicitFieldSchema): FieldSchema {\n\treturn schema instanceof FieldSchema ? schema : createFieldSchema(FieldKind.Required, schema);\n}\n/**\n * Normalizes a {@link ImplicitAllowedTypes} to a set of {@link TreeNodeSchema}s, by eagerly evaluating any\n * lazy schema declarations.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAllowedTypes(types: ImplicitAllowedTypes): ReadonlySet<TreeNodeSchema> {\n\tconst normalized = new Set<TreeNodeSchema>();\n\tif (isReadonlyArray(types)) {\n\t\tfor (const lazyType of types) {\n\t\t\tnormalized.add(evaluateLazySchema(lazyType));\n\t\t}\n\t} else {\n\t\tnormalized.add(evaluateLazySchema(types));\n\t}\n\treturn normalized;\n}\n\nfunction evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {\n\tconst evaluatedSchema = isLazy(value) ? value() : value;\n\tif (evaluatedSchema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,\n\t\t);\n\t}\n\treturn evaluatedSchema;\n}\n\n/**\n * Types allowed in a field.\n * @remarks\n * Implicitly treats a single type as an array of one type.\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Schema for a field of a tree node.\n * @remarks\n * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.\n * @public\n */\nexport type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;\n\n/**\n * Converts ImplicitFieldSchema to the corresponding tree node's field type.\n * @public\n */\nexport type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =\n\tTSchema extends FieldSchema<infer Kind, infer Types>\n\t\t? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false>\n\t\t: TSchema extends ImplicitAllowedTypes\n\t\t? TreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a field of the given schema.\n * @public\n */\nexport type InsertableTreeFieldFromImplicitField<\n\tTSchema extends ImplicitFieldSchema = FieldSchema,\n> = TSchema extends FieldSchema<infer Kind, infer Types>\n\t? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>\n\t: TSchema extends ImplicitAllowedTypes\n\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t: unknown;\n\n/**\n * Suitable for output.\n * For input must error on side of excluding undefined instead.\n * @public\n */\nexport type ApplyKind<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = {\n\t[FieldKind.Required]: T;\n\t[FieldKind.Optional]: T | undefined;\n\t[FieldKind.Identifier]: DefaultsAreOptional extends true ? T | undefined : T;\n}[Kind];\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t? NodeFromSchema<InternalFlexListTypes.FlexListToUnion<TSchema>>\n\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? InsertableTypedNode<TSchema>\n\t: TSchema extends AllowedTypes\n\t? InsertableTypedNode<InternalFlexListTypes.FlexListToUnion<TSchema>>\n\t: never;\n\n/**\n * Takes in `TreeNodeSchema[]` and returns a TypedNode union.\n * @public\n */\nexport type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tinfer TNode\n>\n\t? TNode\n\t: never;\n\n/**\n * Data which can be used as a node to be inserted.\n * Either an unhydrated node, or content to build a new node.\n * @public\n */\nexport type InsertableTypedNode<T extends TreeNodeSchema> =\n\t| (T extends { implicitlyConstructable: true } ? NodeBuilderData<T> : never)\n\t| Unhydrated<NodeFromSchema<T>>;\n\n/**\n * Given a node's schema, return the corresponding object from which the node could be built.\n * @privateRemarks\n * Currently this assumes factory functions take exactly one argument.\n * This could be changed if needed.\n *\n * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.\n * @public\n */\nexport type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tunknown,\n\tinfer TBuild\n>\n\t? TBuild\n\t: never;\n\n/**\n * Value that may be stored as a leaf node.\n * @public\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type TreeLeafValue = number | string | boolean | IFluidHandle | null;\n\n/**\n * The type of a {@link TreeNode}.\n * For moore information about the type, use `Tree.schema(theNode)` instead.\n * @remarks\n * This symbol mainly exists on nodes to allow TypeScript to provide more accurate type checking.\n * `Tree.is` and `Tree.schema` provide a superset of this information in more friendly ways.\n *\n * This symbol should not manually be added to objects as doing so allows the object to be invalidly used where nodes are expected.\n * Instead construct a real node of the desired type using its constructor.\n * @privateRemarks\n * This prevents non-nodes from being accidentally used as nodes, as well as allows the type checker to distinguish different node types.\n * @public\n */\nexport const type: unique symbol = Symbol(\"TreeNode Type\");\n\n/**\n * Adds a {@link \"type\"} field.\n * @public\n */\nexport interface WithType<TName extends string = string> {\n\t/**\n\t * {@inheritdoc \"type\"}\n\t */\n\tget [type](): TName;\n}\n"]}
1
+ {"version":3,"file":"schemaTypes.js","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.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\nimport type { ErasedType, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { Lazy } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype InternalFlexListTypes,\n\ttype LazyItem,\n\ttype NodeKeyManager,\n\tisLazy,\n} from \"../feature-libraries/index.js\";\nimport { type MakeNominal, brand, isReadonlyArray } from \"../util/index.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport type { FieldKey } from \"../core/index.js\";\nimport type { InsertableContent } from \"./proxies.js\";\n\n/**\n * Schema for a tree node.\n * @typeParam Name - The full (including scope) name/identifier for the schema.\n * @typeParam Kind - Which kind of node this schema is for.\n * @typeParam TNode - API for nodes that use this schema.\n * @typeParam TBuild - Data which can be used to construct an {@link Unhydrated} node of this type.\n * @typeParam Info - Data used when defining this schema.\n * @remarks\n * Captures the schema both as runtime data and compile time type information.\n * @public\n */\nexport type TreeNodeSchema<\n\tName extends string = string,\n\tKind extends NodeKind = NodeKind,\n\tTNode = unknown,\n\tTBuild = never,\n\tImplicitlyConstructable extends boolean = boolean,\n\tInfo = unknown,\n> =\n\t| TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>\n\t| TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>;\n\n/**\n * Schema which is not a class.\n * @remarks\n * This is used for schema which cannot have their instances constructed using constructors, like leaf schema.\n * @privateRemarks\n * Non-class based schema can have issues with recursive types due to https://github.com/microsoft/TypeScript/issues/55832.\n * @public\n */\nexport interface TreeNodeSchemaNonClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\tcreate(data: TInsertable): TNode;\n}\n\n/**\n * Tree node schema which is implemented using a class.\n * @remarks\n * Instances of this class are nodes in the tree.\n * This is also a constructor so that it can be subclassed.\n *\n * Using classes in this way allows introducing a named type and a named value at the same time, helping keep the runtime and compile time information together and easy to refer to un a uniform way.\n * Additionally, this works around https://github.com/microsoft/TypeScript/issues/55832 which causes similar patterns with less explicit types to infer \"any\" in the d.ts file.\n * @public\n */\nexport interface TreeNodeSchemaClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\t/**\n\t * Constructs an {@link Unhydrated} node with this schema.\n\t * @remarks\n\t * This constructor is also used internally to construct hydrated nodes with a different parameter type.\n\t * Therefor overriding this constructor is not type-safe and is not supported.\n\t * @sealed\n\t */\n\tnew (data: TInsertable | InternalTreeNode): Unhydrated<TNode>;\n}\n\n/**\n * Data common to all tree node schema.\n * @public\n */\nexport interface TreeNodeSchemaCore<\n\tout Name extends string,\n\tout Kind extends NodeKind,\n\tout ImplicitlyConstructable extends boolean,\n\tout Info = unknown,\n> {\n\treadonly identifier: Name;\n\treadonly kind: Kind;\n\n\t/**\n\t * Data used to define this schema.\n\t *\n\t * @remarks\n\t * The format depends on the kind of node it is for.\n\t * For example, the \"object\" node kind could store the field schema here.\n\t */\n\treadonly info: Info;\n\n\t/**\n\t * When constructing insertable content,\n\t * data that could be passed to the node's constructor can be used instead of an {@link Unhydrated} node\n\t * iff implicitlyConstructable is true.\n\t * @privateRemarks\n\t * Currently the logic for traversing insertable content,\n\t * both to build trees and to hydrate them does not defer to the schema classes to handle the policy,\n\t * so if their constructors differ from what is supported, some cases will not work.\n\t * Setting this to false adjusts the insertable types to disallow cases which could be impacted by these inconsistencies.\n\t */\n\treadonly implicitlyConstructable: ImplicitlyConstructable;\n}\n\n/**\n * Types for use in fields.\n * @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Kind of a field on a node.\n * @public\n */\nexport enum FieldKind {\n\t/**\n\t * A field which can be empty or filled.\n\t * @remarks\n\t * Allows 0 or one child.\n\t */\n\tOptional,\n\t/**\n\t * A field which must always be filled.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tRequired,\n\t/**\n\t * A special field used for node identifiers.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tIdentifier,\n}\n\n/**\n * Kind of tree node.\n * @public\n */\nexport enum NodeKind {\n\t/**\n\t * A node which serves as a map, storing children under string keys.\n\t */\n\tMap,\n\t/**\n\t * A node which serves as an array, storing children in an ordered sequence.\n\t */\n\tArray,\n\t/**\n\t * A node which stores a heterogenous collection of children in named fields.\n\t * @remarks\n\t * Each field gets its own schema.\n\t */\n\tObject,\n\t/**\n\t * A node which stores a single leaf value.\n\t */\n\tLeaf,\n}\n\n/**\n * Maps from a view key to its corresponding {@link FieldProps.key | stored key} for the provided\n * {@link ImplicitFieldSchema | field schema}.\n *\n * @remarks\n * If an explicit stored key was specified in the schema, it will be used.\n * Otherwise, the stored key is the same as the view key.\n */\nexport function getStoredKey(viewKey: string, fieldSchema: ImplicitFieldSchema): FieldKey {\n\treturn brand(getExplicitStoredKey(fieldSchema) ?? viewKey);\n}\n\n/**\n * Gets the {@link FieldProps.key | stored key} specified by the schema, if one was explicitly specified.\n * Otherwise, returns undefined.\n */\nexport function getExplicitStoredKey(fieldSchema: ImplicitFieldSchema): string | undefined {\n\treturn fieldSchema instanceof FieldSchema ? fieldSchema.props?.key : undefined;\n}\n\n/**\n * Additional information to provide to a {@link FieldSchema}.\n *\n * @public\n */\nexport interface FieldProps {\n\t/**\n\t * The unique identifier of a field, used in the persisted form of the tree.\n\t *\n\t * @remarks\n\t * If not explicitly set via the schema, this is the same as the schema's property key.\n\t *\n\t * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.\n\t * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,\n\t * you can change the property key and specify the previous property key as the stored key.\n\t *\n\t * Notes:\n\t *\n\t * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`\n\t * will always return the property keys specified in the schema, ignoring any stored keys that differ from\n\t * the property keys.\n\t *\n\t * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys\n\t * (accounting for those implicitly derived from property keys) contains no duplicates.\n\t * This is validated at runtime.\n\t *\n\t * @example Refactoring code without breaking compatibility with existing data\n\t *\n\t * Consider some existing object schema:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \txPosition: schemaFactory.number,\n\t * \tyPosition: schemaFactory.number,\n\t * \tzPosition: schemaFactory.optional(schemaFactory.number),\n\t * });\n\t * ```\n\t *\n\t * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.\n\t *\n\t * We would like to refactor the schema to omit \"Position\" from the property keys, but application data has\n\t * already been persisted using the original property keys. To maintain compatibility with existing data,\n\t * we can refactor the schema as follows:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \tx: schemaFactory.required(schemaFactory.number, { key: \"xPosition\" }),\n\t * \ty: schemaFactory.required(schemaFactory.number, { key: \"yPosition\" }),\n\t * \tz: schemaFactory.optional(schemaFactory.number, { key: \"zPosition\" }),\n\t * });\n\t * ```\n\t *\n\t * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.\n\t *\n\t * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.\n\t */\n\treadonly key?: string;\n\t/**\n\t * A default provider used for fields which were not provided any values.\n\t * @privateRemarks\n\t * We are using an erased type here, as we want to expose this API but `InsertableContent` and `NodeKeyManager` are not public.\n\t */\n\treadonly defaultProvider?: DefaultProvider;\n}\n\n/**\n * A {@link FieldProvider} which requires additional context in order to produce its content\n */\nexport type ContextualFieldProvider = (context: NodeKeyManager) => InsertableContent | undefined;\n/**\n * A {@link FieldProvider} which can produce its content in a vacuum\n */\nexport type ConstantFieldProvider = () => InsertableContent | undefined;\n/**\n * A function which produces content for a field every time that it is called\n */\nexport type FieldProvider = ContextualFieldProvider | ConstantFieldProvider;\n/**\n * Returns true if the given {@link FieldProvider} is a {@link ConstantFieldProvider}\n */\nexport function isConstant(fieldProvider: FieldProvider): fieldProvider is ConstantFieldProvider {\n\treturn fieldProvider.length === 0;\n}\n\n/**\n * Provides a default value for a field.\n * @remarks\n * If present in a `FieldSchema`, when constructing new tree content that field can be omitted, and a default will be provided.\n * @public\n */\nexport interface DefaultProvider extends ErasedType<\"@fluidframework/tree.FieldProvider\"> {}\n\nexport function extractFieldProvider(input: DefaultProvider): FieldProvider {\n\treturn input as unknown as FieldProvider;\n}\n\nexport function getDefaultProvider(input: FieldProvider): DefaultProvider {\n\treturn input as unknown as DefaultProvider;\n}\n\n/**\n * Package internal construction API.\n */\nexport let createFieldSchema: <\n\tKind extends FieldKind = FieldKind,\n\tTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n>(\n\tkind: Kind,\n\tallowedTypes: Types,\n\tprops?: FieldProps,\n) => FieldSchema<Kind, Types>;\n\n/**\n * All policy for a specific field,\n * including functionality that does not have to be kept consistent across versions or deterministic.\n *\n * This can include policy for how to use this schema for \"view\" purposes, and well as how to expose editing APIs.\n * Use {@link SchemaFactory} to create the FieldSchema instances, for example {@link SchemaFactory.optional}.\n * @privateRemarks\n * Public access to the constructor is removed to prevent creating expressible but unsupported (or not stable) configurations.\n * {@link createFieldSchema} can be used internally to create instances.\n * @sealed @public\n */\nexport class FieldSchema<\n\tout Kind extends FieldKind = FieldKind,\n\tout Types extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n> {\n\tstatic {\n\t\tcreateFieldSchema = <\n\t\t\tKind2 extends FieldKind = FieldKind,\n\t\t\tTypes2 extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\t\t>(\n\t\t\tkind: Kind2,\n\t\t\tallowedTypes: Types2,\n\t\t\tprops?: FieldProps,\n\t\t) => new FieldSchema(kind, allowedTypes, props);\n\t}\n\t/**\n\t * This class is used with instanceof, and therefore should have nominal typing.\n\t * This field enforces that.\n\t */\n\tprotected _typeCheck?: MakeNominal;\n\n\tprivate readonly lazyTypes: Lazy<ReadonlySet<TreeNodeSchema>>;\n\n\t/**\n\t * What types of tree nodes are allowed in this field.\n\t * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.\n\t */\n\tpublic get allowedTypeSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyTypes.value;\n\t}\n\n\tprivate constructor(\n\t\t/**\n\t\t * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.\n\t\t * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.\n\t\t */\n\t\tpublic readonly kind: Kind,\n\t\t/**\n\t\t * What types of tree nodes are allowed in this field.\n\t\t */\n\t\tpublic readonly allowedTypes: Types,\n\t\t/**\n\t\t * Optional properties associated with the field.\n\t\t */\n\t\tpublic readonly props?: FieldProps,\n\t) {\n\t\tthis.lazyTypes = new Lazy(() => normalizeAllowedTypes(this.allowedTypes));\n\t}\n}\n\n/**\n * Normalizes a {@link ImplicitFieldSchema} to a {@link FieldSchema}.\n */\nexport function normalizeFieldSchema(schema: ImplicitFieldSchema): FieldSchema {\n\treturn schema instanceof FieldSchema ? schema : createFieldSchema(FieldKind.Required, schema);\n}\n/**\n * Normalizes a {@link ImplicitAllowedTypes} to a set of {@link TreeNodeSchema}s, by eagerly evaluating any\n * lazy schema declarations.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAllowedTypes(types: ImplicitAllowedTypes): ReadonlySet<TreeNodeSchema> {\n\tconst normalized = new Set<TreeNodeSchema>();\n\tif (isReadonlyArray(types)) {\n\t\tfor (const lazyType of types) {\n\t\t\tnormalized.add(evaluateLazySchema(lazyType));\n\t\t}\n\t} else {\n\t\tnormalized.add(evaluateLazySchema(types));\n\t}\n\treturn normalized;\n}\n\nfunction evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {\n\tconst evaluatedSchema = isLazy(value) ? value() : value;\n\tif (evaluatedSchema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,\n\t\t);\n\t}\n\treturn evaluatedSchema;\n}\n\n/**\n * Types allowed in a field.\n * @remarks\n * Implicitly treats a single type as an array of one type.\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Schema for a field of a tree node.\n * @remarks\n * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.\n * @public\n */\nexport type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;\n\n/**\n * Converts ImplicitFieldSchema to the corresponding tree node's field type.\n * @public\n */\nexport type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =\n\tTSchema extends FieldSchema<infer Kind, infer Types>\n\t\t? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false>\n\t\t: TSchema extends ImplicitAllowedTypes\n\t\t? TreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a field of the given schema.\n * @public\n */\nexport type InsertableTreeFieldFromImplicitField<\n\tTSchema extends ImplicitFieldSchema = FieldSchema,\n> = TSchema extends FieldSchema<infer Kind, infer Types>\n\t? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>\n\t: TSchema extends ImplicitAllowedTypes\n\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t: unknown;\n\n/**\n * Suitable for output.\n * For input must error on side of excluding undefined instead.\n * @public\n */\nexport type ApplyKind<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = {\n\t[FieldKind.Required]: T;\n\t[FieldKind.Optional]: T | undefined;\n\t[FieldKind.Identifier]: DefaultsAreOptional extends true ? T | undefined : T;\n}[Kind];\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t? NodeFromSchema<InternalFlexListTypes.FlexListToUnion<TSchema>>\n\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? InsertableTypedNode<TSchema>\n\t: TSchema extends AllowedTypes\n\t? InsertableTypedNode<InternalFlexListTypes.FlexListToUnion<TSchema>>\n\t: never;\n\n/**\n * Takes in `TreeNodeSchema[]` and returns a TypedNode union.\n * @public\n */\nexport type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tinfer TNode\n>\n\t? TNode\n\t: never;\n\n/**\n * Data which can be used as a node to be inserted.\n * Either an unhydrated node, or content to build a new node.\n * @public\n */\nexport type InsertableTypedNode<T extends TreeNodeSchema> =\n\t| (T extends { implicitlyConstructable: true } ? NodeBuilderData<T> : never)\n\t| Unhydrated<NodeFromSchema<T>>;\n\n/**\n * Given a node's schema, return the corresponding object from which the node could be built.\n * @privateRemarks\n * Currently this assumes factory functions take exactly one argument.\n * This could be changed if needed.\n *\n * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.\n * @public\n */\nexport type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tunknown,\n\tinfer TBuild\n>\n\t? TBuild\n\t: never;\n\n/**\n * Value that may be stored as a leaf node.\n * @public\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type TreeLeafValue = number | string | boolean | IFluidHandle | null;\n\n/**\n * The type of a {@link TreeNode}.\n * For moore information about the type, use `Tree.schema(theNode)` instead.\n * @remarks\n * This symbol mainly exists on nodes to allow TypeScript to provide more accurate type checking.\n * `Tree.is` and `Tree.schema` provide a superset of this information in more friendly ways.\n *\n * This symbol should not manually be added to objects as doing so allows the object to be invalidly used where nodes are expected.\n * Instead construct a real node of the desired type using its constructor.\n * @privateRemarks\n * This prevents non-nodes from being accidentally used as nodes, as well as allows the type checker to distinguish different node types.\n * @public\n */\nexport const type: unique symbol = Symbol(\"TreeNode Type\");\n\n/**\n * Adds a {@link \"type\"} field.\n * @public\n */\nexport interface WithType<TName extends string = string> {\n\t/**\n\t * {@inheritdoc \"type\"}\n\t */\n\tget [type](): TName;\n}\n"]}
@@ -47,26 +47,9 @@ export interface ITree extends IFluidLoadable {
47
47
  * this initialization could become just another out of schema content adapter and this initialization is no longer a special case.
48
48
  */
49
49
  viewWith<TRoot extends ImplicitFieldSchema>(config: TreeViewConfiguration<TRoot>): TreeView<TRoot>;
50
- /**
51
- * Returns a {@link TreeView} using the provided schema.
52
- * If the stored schema is view-compatible with the view schema specified by `config`,
53
- * the returned {@link TreeView} will expose the root with a schema-aware API based on the provided view schema.
54
- * See {@link TreeView.compatibility} for information about the compatibility between the view and stored schemas.
55
- *
56
- * @remarks
57
- * If the tree is uninitialized, it will be implicitly initialized by this function.
58
- *
59
- * 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.
60
- *
61
- * Only one schematized view may exist for a given ITree at a time.
62
- * If creating a second, the first must be disposed before calling `schematize` again.
63
- * @deprecated Replaced by {@link ITree.viewWith}. Use that method instead. Note that `viewWith` does not implicitly initialize the tree:
64
- * to initialize it, call {@link TreeView.initialize} on the returned view.
65
- */
66
- schematize<TRoot extends ImplicitFieldSchema>(config: TreeConfiguration<TRoot>): TreeView<TRoot>;
67
50
  }
68
51
  /**
69
- * Options when schematizing a tree.
52
+ * Options when constructing a tree view.
70
53
  * @public
71
54
  */
72
55
  export interface ITreeConfigurationOptions {
@@ -290,10 +273,6 @@ export interface SchemaCompatibilityStatus {
290
273
  * @public
291
274
  */
292
275
  export interface TreeViewEvents {
293
- /**
294
- * A batch of changes has finished processing and the view has been updated.
295
- */
296
- afterBatch(): void;
297
276
  /**
298
277
  * Raised whenever {@link TreeView.root} is invalidated.
299
278
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":"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"}
@@ -13,14 +13,6 @@ const defaultTreeConfigurationOptions = {
13
13
  * @public
14
14
  */
15
15
  class TreeViewConfiguration {
16
- /**
17
- * {@inheritDoc ITreeViewConfiguration.schema}
18
- */
19
- schema;
20
- /**
21
- * {@inheritDoc ITreeViewConfiguration.enableSchemaValidation}
22
- */
23
- enableSchemaValidation;
24
16
  /**
25
17
  * @param props - Property bag of configuration options.
26
18
  */
@@ -37,19 +29,6 @@ exports.TreeViewConfiguration = TreeViewConfiguration;
37
29
  * @deprecated Please migrate to use {@link TreeViewConfiguration} with {@link ITree.viewWith} instead.
38
30
  */
39
31
  class TreeConfiguration {
40
- schema;
41
- initialTree;
42
- /**
43
- * If `true`, the tree will validate new content against its stored schema at insertion time
44
- * and throw an error if the new content doesn't match the expected schema.
45
- *
46
- * @defaultValue `false`.
47
- *
48
- * @remarks Enabling schema validation has a performance penalty when inserting new content into the tree because
49
- * additional checks are done. Enable this option only in scenarios where you are ok with that operation being a
50
- * bit slower.
51
- */
52
- enableSchemaValidation;
53
32
  /**
54
33
  * @param schema - The schema which the application wants to view the tree with.
55
34
  * @param initialTree - A function that returns the default tree content to initialize the tree with iff the tree is uninitialized
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/simple-tree/tree.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAgGH,MAAM,+BAA+B,GAAwC;IAC5E,sBAAsB,EAAE,KAAK;CAC7B,CAAC;AAyBF;;;GAGG;AACH,MAAa,qBAAqB;IAGjC;;OAEG;IACa,MAAM,CAAU;IAEhC;;OAEG;IACa,sBAAsB,CAAU;IAEhD;;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;AArBD,sDAqBC;AAED;;;;GAIG;AACH,MAAa,iBAAiB;IAsBZ;IACA;IAtBjB;;;;;;;;;OASG;IACa,sBAAsB,CAAU;IAEhD;;;;;;;OAOG;IACH,YACiB,MAAe,EACf,WAAgE,EAChF,OAAmC;QAFnB,WAAM,GAAN,MAAM,CAAS;QACf,gBAAW,GAAX,WAAW,CAAqD;QAGhF,IAAI,CAAC,sBAAsB;YAC1B,OAAO,EAAE,sBAAsB;gBAC/B,+BAA+B,CAAC,sBAAsB,CAAC;IACzD,CAAC;CACD;AA9BD,8CA8BC","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 * @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\t/**\n\t * Returns a {@link TreeView} using the provided schema.\n\t * If the stored schema is view-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 * See {@link TreeView.compatibility} for information about the compatibility between the view and stored schemas.\n\t *\n\t * @remarks\n\t * If the tree is uninitialized, it will be implicitly initialized by this function.\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 `schematize` again.\n\t * @deprecated Replaced by {@link ITree.viewWith}. Use that method instead. Note that `viewWith` does not implicitly initialize the tree:\n\t * to initialize it, call {@link TreeView.initialize} on the returned view.\n\t */\n\tschematize<TRoot extends ImplicitFieldSchema>(\n\t\tconfig: TreeConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * Options when schematizing a tree.\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<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> {\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 * @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 * Configuration for how to {@link ITree.schematize | schematize} a tree.\n * @public\n * @deprecated Please migrate to use {@link TreeViewConfiguration} with {@link ITree.viewWith} instead.\n */\nexport class TreeConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> {\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\tpublic readonly enableSchemaValidation: boolean;\n\n\t/**\n\t * @param schema - The schema which the application wants to view the tree with.\n\t * @param initialTree - A function that returns the default tree content to initialize the tree with iff the tree is uninitialized\n\t * (meaning it does not even have any schema set at all).\n\t * If `initialTree` returns any actual node instances, they should be recreated each time `initialTree` runs.\n\t * This is because if the config is used a second time any nodes that were not recreated could error since nodes cannot be inserted into the tree multiple times.\n\t * @param options - Additional options that can be specified when {@link ITree.schematize | schematizing } a tree.\n\t */\n\tpublic constructor(\n\t\tpublic readonly schema: TSchema,\n\t\tpublic readonly initialTree: () => InsertableTreeFieldFromImplicitField<TSchema>,\n\t\toptions?: ITreeConfigurationOptions,\n\t) {\n\t\tthis.enableSchemaValidation =\n\t\t\toptions?.enableSchemaValidation ??\n\t\t\tdefaultTreeConfigurationOptions.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 * @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 * @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 * @public\n */\nexport interface TreeViewEvents {\n\t/**\n\t * A batch of changes has finished processing and the view has been updated.\n\t */\n\tafterBatch(): void;\n\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;;;AA4EH,MAAM,+BAA+B,GAAwC;IAC5E,sBAAsB,EAAE,KAAK;CAC7B,CAAC;AAyBF;;;GAGG;AACH,MAAa,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;AArBD,sDAqBC;AAED;;;;GAIG;AACH,MAAa,iBAAiB;IAa7B;;;;;;;OAOG;IACH,YACiB,MAAe,EACf,WAAgE,EAChF,OAAmC;QAFnB,WAAM,GAAN,MAAM,CAAS;QACf,gBAAW,GAAX,WAAW,CAAqD;QAGhF,IAAI,CAAC,sBAAsB;YAC1B,OAAO,EAAE,sBAAsB;gBAC/B,+BAA+B,CAAC,sBAAsB,CAAC;IACzD,CAAC;CACD;AA9BD,8CA8BC","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 * @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<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> {\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 * @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 * Configuration for how to {@link ITree.schematize | schematize} a tree.\n * @public\n * @deprecated Please migrate to use {@link TreeViewConfiguration} with {@link ITree.viewWith} instead.\n */\nexport class TreeConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> {\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\tpublic readonly enableSchemaValidation: boolean;\n\n\t/**\n\t * @param schema - The schema which the application wants to view the tree with.\n\t * @param initialTree - A function that returns the default tree content to initialize the tree with iff the tree is uninitialized\n\t * (meaning it does not even have any schema set at all).\n\t * If `initialTree` returns any actual node instances, they should be recreated each time `initialTree` runs.\n\t * This is because if the config is used a second time any nodes that were not recreated could error since nodes cannot be inserted into the tree multiple times.\n\t * @param options - Additional options that can be specified when {@link ITree.schematize | schematizing } a tree.\n\t */\n\tpublic constructor(\n\t\tpublic readonly schema: TSchema,\n\t\tpublic readonly initialTree: () => InsertableTreeFieldFromImplicitField<TSchema>,\n\t\toptions?: ITreeConfigurationOptions,\n\t) {\n\t\tthis.enableSchemaValidation =\n\t\t\toptions?.enableSchemaValidation ??\n\t\t\tdefaultTreeConfigurationOptions.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 * @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 * @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 * @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"]}
@@ -54,11 +54,20 @@ export interface TreeNodeApi {
54
54
  */
55
55
  readonly status: (node: TreeNode) => TreeStatus;
56
56
  /**
57
- * Returns the {@link FieldKind.Identifier | identifier} of the given node in the most compressed form possible.
57
+ * Returns the {@link SchemaFactory.identifier | identifier} of the given node in the most compressed form possible.
58
58
  * @remarks
59
- * If the node's identifier is a valid `StableNodeKey`, then this will return a unique process-local integer corresponding to that identifier.
60
- * If the node's identifier is any other string, then this will return that string.
61
- * If the node has no identifier (that is, it has no field of an {@link FieldKind.Identifier | identifier} field kind), then this returns undefined.
59
+ * 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.
60
+ * 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.
61
+ *
62
+ * If the node's identifier is any other user-provided string, then this will return that string.
63
+ *
64
+ * If the node has no identifier (that is, it has no {@link SchemaFactory.identifier | identifier} field), then this returns `undefined`.
65
+ *
66
+ * If the node has more than one identifier, then this will throw an error.
67
+ *
68
+ * The returned integer must not be serialized or preserved outside of the current process.
69
+ * 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.
70
+ * 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.
62
71
  */
63
72
  shortId(node: TreeNode): number | string | undefined;
64
73
  }
@@ -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;AAU3C;;;;;;;;GAQG;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;;;;;;OAMG;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;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,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;;;;;;;;GAQG;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"}
@@ -15,6 +15,7 @@ const schemaCaching_js_1 = require("./schemaCaching.js");
15
15
  const schemaTypes_js_1 = require("./schemaTypes.js");
16
16
  const leafNodeSchema_js_1 = require("./leafNodeSchema.js");
17
17
  const internal_2 = require("@fluidframework/runtime-utils/internal");
18
+ const internal_3 = require("@fluidframework/telemetry-utils/internal");
18
19
  /**
19
20
  * The `Tree` object holds various functions for analyzing {@link TreeNode}s.
20
21
  */
@@ -80,17 +81,21 @@ exports.treeNodeApi = {
80
81
  },
81
82
  shortId(node) {
82
83
  const flexNode = (0, proxyBinding_js_1.getFlexNode)(node);
84
+ let shortId;
83
85
  for (const field of flexNode.boxedIterator()) {
84
86
  if (field.schema.kind === index_js_2.FieldKinds.identifier) {
87
+ if (shortId !== undefined) {
88
+ throw new internal_3.UsageError("shortId() may not be called on a node with more than one identifier. Consider converting extraneous identifier fields to string fields.");
89
+ }
85
90
  const identifier = field.boxedAt(0);
86
91
  (0, internal_1.assert)(identifier !== undefined, 0x927 /* The identifier must exist */);
87
92
  const identifierValue = identifier.value;
88
93
  const localNodeKey = identifier.context.nodeKeyManager.tryLocalizeNodeKey(identifierValue);
89
- return localNodeKey !== undefined
90
- ? (0, index_js_3.extractFromOpaque)(localNodeKey)
91
- : identifierValue;
94
+ shortId =
95
+ localNodeKey !== undefined ? (0, index_js_3.extractFromOpaque)(localNodeKey) : identifierValue;
92
96
  }
93
97
  }
98
+ return shortId;
94
99
  },
95
100
  };
96
101
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"treeNodeApi.js","sourceRoot":"","sources":["../../src/simple-tree/treeNodeApi.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\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\";\n\n/**\n * Provides various functions for analyzing {@link TreeNode}s.\n *\n * @privateRemarks\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 * @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 FieldKind.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 `StableNodeKey`, then this will return a unique process-local integer corresponding to that identifier.\n\t * If the node's identifier is any other string, then this will return that string.\n\t * If the node has no identifier (that is, it has no field of an {@link FieldKind.Identifier | identifier} field kind), then this returns undefined.\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\tfor (const field of flexNode.boxedIterator()) {\n\t\t\tif (field.schema.kind === FieldKinds.identifier) {\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\t\t\t\treturn localNodeKey !== undefined\n\t\t\t\t\t? extractFromOpaque(localNodeKey)\n\t\t\t\t\t: identifierValue;\n\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\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 * @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":"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","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 *\n * @privateRemarks\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 * @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 * @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"]}
@@ -16,7 +16,7 @@ import { type FlexTreeNode, type MapTreeNode } from "../feature-libraries/index.
16
16
  */
17
17
  export type Unhydrated<T> = T;
18
18
  /**
19
- * A non-leaf SharedTree node. Includes objects, arrays, and maps.
19
+ * A non-{@link NodeKind.Leaf|leaf} SharedTree node. Includes objects, arrays, and maps.
20
20
  *
21
21
  * @remarks
22
22
  * Base type which all nodes implement.
@@ -34,11 +34,8 @@ export type Unhydrated<T> = T;
34
34
  *
35
35
  * Not all node implementations include this in their prototype chain (some hide it with a proxy),
36
36
  * and thus cause the default/built in `instanceof` to return false despite our type checking and all other APIs treating them as TreeNodes.
37
- * This results in the runtime and compile time behavior of `instanceof` differing.
38
- * TypeScript 5.3 allows altering the compile time behavior of `instanceof`.
39
- * The runtime behavior can be changed by implementing `Symbol.hasInstance`.
40
- * One of those approaches could be used to resolve this inconsistency,
41
- * but for now the type-only export prevents use of `instanceof` avoiding this problem in the public API.
37
+ * This class provides a custom `Symbol.hasInstance` to fix `instanceof` for this class and all classes extending it.
38
+ * For now the type-only export prevents use of `instanceof` on this class (but allows it in subclasses like schema classes).
42
39
  * @public
43
40
  */
44
41
  export declare abstract class TreeNode implements WithType {
@@ -49,8 +46,31 @@ export declare abstract class TreeNode implements WithType {
49
46
  * Subclasses provide more specific strings for this to get strong typing of otherwise type compatible nodes.
50
47
  */
51
48
  abstract get [type](): string;
49
+ /**
50
+ * Provides `instanceof` support for testing if a value is a `TreeNode`.
51
+ * @remarks
52
+ * For more options, like including leaf values or narrowing to collections of schema, use `is` or `schema` from {@link TreeNodeApi}.
53
+ * @privateRemarks
54
+ * Due to type-only export, this functionality is not available outside the package.
55
+ */
56
+ static [Symbol.hasInstance](value: unknown): value is TreeNode;
57
+ /**
58
+ * Provides `instanceof` support for all schema classes with public constructors.
59
+ * @remarks
60
+ * For more options, like including leaf values or narrowing to collections of schema, use `is` or `schema` from {@link TreeNodeApi}.
61
+ * @privateRemarks
62
+ * Despite type-only export, this functionality is available outside the package since it is inherited by subclasses.
63
+ */
64
+ static [Symbol.hasInstance]<TSchema extends abstract new (...args: any[]) => TreeNode>(this: TSchema, value: unknown): value is InstanceType<TSchema>;
52
65
  protected constructor();
53
66
  }
67
+ /**
68
+ * Check if the prototype derived's prototype chain contains `base`.
69
+ * @param derived - prototype to check
70
+ * @param base - prototype to search for
71
+ * @returns true iff `base` is in the prototype chain starting at `derived`.
72
+ */
73
+ export declare function inPrototypeChain(derived: object | null, base: object): boolean;
54
74
  /**
55
75
  * Class which all {@link TreeNode}s must extend.
56
76
  * Since this is not exported, it allows robust detection of attempts to create TreeNodes which do not go through SchemaFactory which is the only place which exposes classes that extend this.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/simple-tree/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAGlE,OAAO,EAAuB,KAAK,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,WAAW,EAGhB,MAAM,+BAA+B,CAAC;AAQvC;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,8BAAsB,QAAS,YAAW,QAAQ;;IA6BjD;;;;OAIG;IACH,aAAoB,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;IAErC,SAAS;CAKT;AAED;;;;;;;GAOG;AACH,8BAAsB,aAAa,CAAC,MAAM,CAAE,SAAQ,QAAQ;IAC3D;;;;;;;OAOG;IACH,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EACjC,IAAI,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,EAC7B,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,KAAK,EAAE,YAAY,GACjB,aAAa,CAAC,CAAC,CAAC;IAInB;;OAEG;IACH,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAC9B,IAAI,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,EAC7B,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,GACN,WAAW;IAId;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAErE;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,aAAa,GAAG,SAAS,CAAiB;gBAElE,KAAK,EAAE,MAAM,GAAG,gBAAgB;CAwDnD;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAiB,SAAQ,UAAU,CAAC,uCAAuC,CAAC;CAAG;AAEhG,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAGnE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/simple-tree/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAGlE,OAAO,EAAiC,KAAK,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,WAAW,EAGhB,MAAM,+BAA+B,CAAC;AASvC;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,8BAAsB,QAAS,YAAW,QAAQ;;IA6BjD;;;;OAIG;IACH,aAAoB,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;IAErC;;;;;;OAMG;WACW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ;IAErE;;;;;;OAMG;WACW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,QAAQ,EAC3F,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACZ,KAAK,IAAI,YAAY,CAAC,OAAO,CAAC;IAajC,SAAS;CAKT;AAED;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAS9E;AAED;;;;;;;GAOG;AACH,8BAAsB,aAAa,CAAC,MAAM,CAAE,SAAQ,QAAQ;IAC3D;;;;;;;OAOG;IACH,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EACjC,IAAI,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,EAC7B,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,KAAK,EAAE,YAAY,GACjB,aAAa,CAAC,CAAC,CAAC;IAInB;;OAEG;IACH,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAC9B,IAAI,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,EAC7B,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,GACN,WAAW;IAId;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAErE;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,aAAa,GAAG,SAAS,CAAiB;gBAElE,KAAK,EAAE,MAAM,GAAG,gBAAgB;CAwDnD;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAiB,SAAQ,UAAU,CAAC,uCAAuC,CAAC;CAAG;AAEhG,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAGnE"}