@fluidframework/tree 2.103.0 → 2.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/api-report/tree.alpha.api.md +12 -3
  3. package/api-report/tree.beta.api.md +11 -3
  4. package/api-report/tree.legacy.beta.api.md +11 -3
  5. package/dist/codec/versioned/format.js +2 -24
  6. package/dist/codec/versioned/format.js.map +1 -1
  7. package/dist/core/rebase/types.js +2 -24
  8. package/dist/core/rebase/types.js.map +1 -1
  9. package/dist/core/schema-stored/formatV1.js +2 -24
  10. package/dist/core/schema-stored/formatV1.js.map +1 -1
  11. package/dist/core/schema-stored/formatV2.js +2 -24
  12. package/dist/core/schema-stored/formatV2.js.map +1 -1
  13. package/dist/core/schema-stored/index.js +3 -25
  14. package/dist/core/schema-stored/index.js.map +1 -1
  15. package/dist/core/tree/anchorSet.js +4 -8
  16. package/dist/core/tree/anchorSet.js.map +1 -1
  17. package/dist/core/tree/detachedFieldIndexFormatCommon.js +2 -24
  18. package/dist/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
  19. package/dist/core/tree/detachedFieldIndexFormatV2.js +2 -24
  20. package/dist/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
  21. package/dist/core/tree/persistedTreeTextFormat.js +2 -24
  22. package/dist/core/tree/persistedTreeTextFormat.js.map +1 -1
  23. package/dist/entrypoints/internal.js +2 -15
  24. package/dist/entrypoints/internal.js.map +1 -1
  25. package/dist/feature-libraries/chunked-forest/chunkedForest.js +7 -11
  26. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  27. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +2 -24
  28. package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
  29. package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js +2 -24
  30. package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js.map +1 -1
  31. package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js +2 -24
  32. package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js.map +1 -1
  33. package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js +2 -24
  34. package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js.map +1 -1
  35. package/dist/feature-libraries/flex-tree/lazyEntity.js +9 -19
  36. package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  37. package/dist/feature-libraries/flex-tree/lazyNode.js +3 -13
  38. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  39. package/dist/feature-libraries/forest-summary/formatCommon.js +2 -24
  40. package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
  41. package/dist/feature-libraries/index.js +2 -24
  42. package/dist/feature-libraries/index.js.map +1 -1
  43. package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js +2 -24
  44. package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
  45. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  46. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +10 -30
  47. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  48. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -24
  49. package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
  50. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +2 -24
  51. package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
  52. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +0 -5
  53. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  54. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  55. package/dist/feature-libraries/object-forest/objectForest.js +11 -55
  56. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  57. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js +2 -24
  58. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js.map +1 -1
  59. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js +2 -24
  60. package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js.map +1 -1
  61. package/dist/feature-libraries/schema-edits/schemaChangeFormat.js +2 -24
  62. package/dist/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
  63. package/dist/feature-libraries/schema-index/formatV1.js +2 -24
  64. package/dist/feature-libraries/schema-index/formatV1.js.map +1 -1
  65. package/dist/feature-libraries/schema-index/formatV2.js +2 -24
  66. package/dist/feature-libraries/schema-index/formatV2.js.map +1 -1
  67. package/dist/feature-libraries/sequence-field/formatV1.js +2 -24
  68. package/dist/feature-libraries/sequence-field/formatV1.js.map +1 -1
  69. package/dist/feature-libraries/sequence-field/formatV2.js +2 -24
  70. package/dist/feature-libraries/sequence-field/formatV2.js.map +1 -1
  71. package/dist/feature-libraries/sequence-field/formatV3.js +2 -24
  72. package/dist/feature-libraries/sequence-field/formatV3.js.map +1 -1
  73. package/dist/index.js +2 -24
  74. package/dist/index.js.map +1 -1
  75. package/dist/packageVersion.d.ts +1 -1
  76. package/dist/packageVersion.js +1 -1
  77. package/dist/packageVersion.js.map +1 -1
  78. package/dist/shared-tree/schematizingTreeView.d.ts +1 -0
  79. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  80. package/dist/shared-tree/schematizingTreeView.js +7 -41
  81. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  82. package/dist/shared-tree/sharedTree.d.ts +0 -1
  83. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  84. package/dist/shared-tree/sharedTree.js +6 -45
  85. package/dist/shared-tree/sharedTree.js.map +1 -1
  86. package/dist/shared-tree/sharedTreeChangeFormat.js +2 -24
  87. package/dist/shared-tree/sharedTreeChangeFormat.js.map +1 -1
  88. package/dist/shared-tree/treeCheckout.d.ts +12 -3
  89. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  90. package/dist/shared-tree/treeCheckout.js +106 -136
  91. package/dist/shared-tree/treeCheckout.js.map +1 -1
  92. package/dist/shared-tree-core/branch.js +13 -17
  93. package/dist/shared-tree-core/branch.js.map +1 -1
  94. package/dist/shared-tree-core/editManagerFormatCommons.js +2 -24
  95. package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
  96. package/dist/shared-tree-core/editManagerFormatV1toV4.js +2 -24
  97. package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
  98. package/dist/shared-tree-core/editManagerFormatVSharedBranches.js +2 -24
  99. package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
  100. package/dist/shared-tree-core/messageCodecVSharedBranches.js +2 -24
  101. package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
  102. package/dist/shared-tree-core/messageFormatV1ToV4.js +2 -24
  103. package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
  104. package/dist/shared-tree-core/messageFormatVSharedBranches.js +2 -24
  105. package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
  106. package/dist/shared-tree-core/sharedTreeCore.js +6 -43
  107. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  108. package/dist/shared-tree-core/transaction.js +20 -30
  109. package/dist/shared-tree-core/transaction.js.map +1 -1
  110. package/dist/simple-tree/api/simpleSchemaCodec.js +2 -24
  111. package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
  112. package/dist/simple-tree/api/snapshotCompatibilityChecker.js +2 -24
  113. package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
  114. package/dist/simple-tree/api/tree.d.ts +10 -0
  115. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  116. package/dist/simple-tree/api/tree.js.map +1 -1
  117. package/dist/simple-tree/core/treeNodeKernel.js +83 -93
  118. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  119. package/dist/simple-tree/core/unhydratedFlexTree.js +6 -10
  120. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  121. package/dist/simple-tree/leafNodeSchema.js +2 -12
  122. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  123. package/dist/simple-tree/node-kinds/array/arrayNode.js +2 -6
  124. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  125. package/dist/simple-tree/simpleSchemaFormatV1.js +2 -24
  126. package/dist/simple-tree/simpleSchemaFormatV1.js.map +1 -1
  127. package/dist/tableSchema.d.ts +50 -4
  128. package/dist/tableSchema.d.ts.map +1 -1
  129. package/dist/tableSchema.js +202 -106
  130. package/dist/tableSchema.js.map +1 -1
  131. package/dist/util/arrayUtilities.d.ts +20 -0
  132. package/dist/util/arrayUtilities.d.ts.map +1 -1
  133. package/dist/util/arrayUtilities.js +24 -1
  134. package/dist/util/arrayUtilities.js.map +1 -1
  135. package/dist/util/index.d.ts +1 -1
  136. package/dist/util/index.d.ts.map +1 -1
  137. package/dist/util/index.js +3 -2
  138. package/dist/util/index.js.map +1 -1
  139. package/dist/util/rangeMap.d.ts +13 -0
  140. package/dist/util/rangeMap.d.ts.map +1 -1
  141. package/dist/util/rangeMap.js +69 -8
  142. package/dist/util/rangeMap.js.map +1 -1
  143. package/dist/util/typeboxBrand.js +2 -24
  144. package/dist/util/typeboxBrand.js.map +1 -1
  145. package/dist/util/utils.js +2 -24
  146. package/dist/util/utils.js.map +1 -1
  147. package/eslint.config.mts +0 -30
  148. package/lib/core/tree/anchorSet.js +1 -5
  149. package/lib/core/tree/anchorSet.js.map +1 -1
  150. package/lib/feature-libraries/chunked-forest/chunkedForest.js +1 -5
  151. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  152. package/lib/feature-libraries/flex-tree/lazyEntity.js +1 -11
  153. package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  154. package/lib/feature-libraries/flex-tree/lazyNode.js +1 -11
  155. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  156. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  157. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +10 -30
  158. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  159. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +0 -5
  160. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  161. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  162. package/lib/feature-libraries/object-forest/objectForest.js +1 -45
  163. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  164. package/lib/packageVersion.d.ts +1 -1
  165. package/lib/packageVersion.js +1 -1
  166. package/lib/packageVersion.js.map +1 -1
  167. package/lib/shared-tree/schematizingTreeView.d.ts +1 -0
  168. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  169. package/lib/shared-tree/schematizingTreeView.js +4 -38
  170. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  171. package/lib/shared-tree/sharedTree.d.ts +0 -1
  172. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  173. package/lib/shared-tree/sharedTree.js +1 -40
  174. package/lib/shared-tree/sharedTree.js.map +1 -1
  175. package/lib/shared-tree/treeCheckout.d.ts +12 -3
  176. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  177. package/lib/shared-tree/treeCheckout.js +62 -92
  178. package/lib/shared-tree/treeCheckout.js.map +1 -1
  179. package/lib/shared-tree-core/branch.js +1 -5
  180. package/lib/shared-tree-core/branch.js.map +1 -1
  181. package/lib/shared-tree-core/sharedTreeCore.js +1 -38
  182. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  183. package/lib/shared-tree-core/transaction.js +1 -11
  184. package/lib/shared-tree-core/transaction.js.map +1 -1
  185. package/lib/simple-tree/api/tree.d.ts +10 -0
  186. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  187. package/lib/simple-tree/api/tree.js.map +1 -1
  188. package/lib/simple-tree/core/treeNodeKernel.js +1 -11
  189. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  190. package/lib/simple-tree/core/unhydratedFlexTree.js +1 -5
  191. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  192. package/lib/simple-tree/leafNodeSchema.js +1 -11
  193. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  194. package/lib/simple-tree/node-kinds/array/arrayNode.js +1 -5
  195. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  196. package/lib/tableSchema.d.ts +50 -4
  197. package/lib/tableSchema.d.ts.map +1 -1
  198. package/lib/tableSchema.js +171 -75
  199. package/lib/tableSchema.js.map +1 -1
  200. package/lib/util/arrayUtilities.d.ts +20 -0
  201. package/lib/util/arrayUtilities.d.ts.map +1 -1
  202. package/lib/util/arrayUtilities.js +22 -0
  203. package/lib/util/arrayUtilities.js.map +1 -1
  204. package/lib/util/index.d.ts +1 -1
  205. package/lib/util/index.d.ts.map +1 -1
  206. package/lib/util/index.js +1 -1
  207. package/lib/util/index.js.map +1 -1
  208. package/lib/util/rangeMap.d.ts +13 -0
  209. package/lib/util/rangeMap.d.ts.map +1 -1
  210. package/lib/util/rangeMap.js +69 -8
  211. package/lib/util/rangeMap.js.map +1 -1
  212. package/package.json +24 -23
  213. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +14 -47
  214. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +0 -5
  215. package/src/packageVersion.ts +1 -1
  216. package/src/shared-tree/schematizingTreeView.ts +4 -0
  217. package/src/shared-tree/sharedTree.ts +2 -6
  218. package/src/shared-tree/treeCheckout.ts +59 -51
  219. package/src/simple-tree/api/tree.ts +11 -0
  220. package/src/tableSchema.ts +306 -80
  221. package/src/util/arrayUtilities.ts +35 -0
  222. package/src/util/index.ts +2 -0
  223. package/src/util/rangeMap.ts +108 -9
  224. package/tsconfig.json +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../../src/simple-tree/api/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4mBH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC9B,IAAuB;IAEvB,OAAO,IAA8B,CAAC;AACvC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IFluidLoadable, IDisposable, Listenable } from \"@fluidframework/core-interfaces\";\n\nimport type {\n\tChangeMetadata,\n\tCommitMetadata,\n\tRevertibleAlphaFactory,\n\tRevertibleFactory,\n} from \"../../core/index.js\";\n// This is referenced by doc comments.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { TreeStatus } from \"../../feature-libraries/index.js\";\nimport type {\n\t// This is referenced by doc comments.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports\n\tTreeAlpha,\n} from \"../../shared-tree/index.js\";\nimport type { JsonCompatibleReadOnly } from \"../../util/index.js\";\n// This is referenced by doc comments.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { Unhydrated } from \"../core/index.js\";\nimport type {\n\tImplicitFieldSchema,\n\tInsertableField,\n\tInsertableTreeFieldFromImplicitField,\n\tReadableField,\n\tReadSchema,\n\tTreeFieldFromImplicitField,\n} from \"../fieldSchema.js\";\nimport type { SimpleTreeSchema } from \"../simpleSchema.js\";\nimport type { UnsafeUnknownSchema } from \"../unsafeUnknownSchema.js\";\n\nimport type { TreeViewConfiguration } from \"./configuration.js\";\nimport type {\n\tRunTransactionParams,\n\tTransactionCallbackStatus,\n\tTransactionResult,\n\tTransactionResultExt,\n\tVoidTransactionCallbackStatus,\n\tWithValue,\n} from \"./transactionTypes.js\";\nimport type { VerboseTree } from \"./verboseTree.js\";\n\n/**\n * A tree from which a {@link TreeView} can be created.\n *\n * @privateRemarks\n * TODO:\n * Add stored key versions of {@link (TreeAlpha:interface).(exportVerbose:2)}, {@link (TreeAlpha:interface).(exportConcise:2)} and {@link (TreeAlpha:interface).exportCompressed} here so tree content can be accessed without a view schema.\n * Add exportSimpleSchema and exportJsonSchema methods (which should exactly match the concise format, and match the free functions for exporting view schema).\n * Maybe rename \"exportJsonSchema\" to align on \"concise\" terminology.\n * Ensure schema exporting APIs here align and reference APIs for exporting view schema to the same formats (which should include stored vs property key choice).\n * Make sure users of independentView can use these export APIs (maybe provide a reference back to the ViewableTree from the TreeView to accomplish that).\n * @system @sealed @public\n */\nexport interface ViewableTree {\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: Support adapters for handling out-of-schema data.\n\t */\n\tviewWith<TRoot extends ImplicitFieldSchema>(\n\t\tconfig: TreeViewConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * Channel for a Fluid Tree DDS.\n * @remarks\n * Allows storing and collaboratively editing schema-aware hierarchial data.\n * @sealed @public\n */\nexport interface ITree extends ViewableTree, IFluidLoadable {}\n\n/**\n * {@link ITree} extended with some alpha APIs.\n * @sealed @alpha\n */\nexport interface ITreeAlpha extends ITree {\n\t/**\n\t * Exports root in the same format as {@link (TreeAlpha:interface).(exportVerbose:1)} using stored keys.\n\t * @remarks\n\t * This is `undefined` if and only if the root field is empty (this can only happen if the root field is optional).\n\t */\n\texportVerbose(): VerboseTree | undefined;\n\n\t/**\n\t * Exports the SimpleTreeSchema that is stored in the tree, using stored keys for object fields.\n\t * @remarks\n\t * To get the schema using property keys, use {@link getSimpleSchema} on the view schema.\n\t */\n\texportSimpleSchema(): SimpleTreeSchema;\n\n\t/**\n\t * Creates a fork of the current state of the main branch.\n\t * This new branch will be shared with and editable by all clients.\n\t */\n\tcreateSharedBranch(): string;\n\n\t/**\n\t * Returns a list of all shared branches that currently exist on this tree.\n\t * Any one of them can be checked out using {@link ITreeAlpha.viewSharedBranchWith}.\n\t */\n\tgetSharedBranchIds(): string[];\n\n\t/**\n\t * Returns a view of the tree on the specified shared branch, using the provided schema.\n\t * See {@link ViewableTree.viewWith}.\n\t */\n\tviewSharedBranchWith<TRoot extends ImplicitFieldSchema>(\n\t\tbranchId: string,\n\t\tconfig: TreeViewConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * A collection of functionality associated with a (version-control-style) branch of a SharedTree.\n * @remarks A `TreeBranch` allows for the {@link TreeBranch.fork | creation of branches} and for those branches to later be {@link TreeBranch.merge | merged}.\n *\n * The branch associated directly with the {@link ITree | SharedTree} is the \"main\" branch, and all other branches fork (directly or transitively) from that main branch.\n *\n * See {@link TreeBranchAlpha} for additional APIs that are in an earlier stage of development.\n * @sealed @beta\n */\nexport interface TreeBranch extends IDisposable {\n\t/**\n\t * Fork a new branch off of this branch which is based off of this branch's current state.\n\t * @remarks Any changes to the tree on the new branch will not apply to this branch until the new branch is e.g. {@link TreeBranch.merge | merged} back into this branch.\n\t * The branch should be disposed when no longer needed, either {@link TreeBranch.dispose | explicitly} or {@link TreeBranch.merge | implicitly when merging} into another branch.\n\t */\n\tfork(): TreeBranch;\n\n\t/**\n\t * Apply all the new changes on the given branch to this branch.\n\t * @param branch - a branch which was created by a call to `branch()`.\n\t * @param disposeMerged - whether or not to dispose `branch` after the merge completes.\n\t * Defaults to true.\n\t * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.\n\t * @remarks All ongoing transactions (if any) in `branch` will be committed before the merge.\n\t */\n\tmerge(branch: TreeBranch, disposeMerged?: boolean): void;\n\n\t/**\n\t * Advance this branch forward such that all new changes on the target branch become part of this branch.\n\t * @param branch - The branch to rebase onto.\n\t * @remarks After rebasing, this branch will be \"ahead\" of the target branch, that is, its unique changes will have been recreated as if they happened after all changes on the target branch.\n\t * This method may only be called on branches produced via {@link TreeBranch.fork | branch} - attempting to rebase the main branch will throw.\n\t *\n\t * Rebasing long-lived branches is important to avoid consuming memory unnecessarily.\n\t * In particular, the SharedTree retains all sequenced changes made to the tree since the \"most-behind\" branch was created or last rebased.\n\t *\n\t * The {@link TreeBranch | main branch} cannot be rebased onto another branch - attempting to do so will throw an error.\n\t */\n\trebaseOnto(branch: TreeBranch): void;\n\n\t/**\n\t * Dispose of this branch, cleaning up any resources associated with it.\n\t * @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.\n\t * @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.\n\t *\n\t * Disposing branches is important to avoid consuming memory unnecessarily.\n\t * In particular, the SharedTree retains all sequenced changes made to the tree since the \"most-behind\" branch was created or last {@link TreeBranch.rebaseOnto | rebased}.\n\t *\n\t * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.\n\t */\n\tdispose(error?: Error): void;\n}\n\n/**\n * Provides additional APIs that may be used to interact with a tree node or a tree node's SharedTree.\n * @alpha\n */\nexport interface TreeContextAlpha {\n\t/**\n\t * Run a synchronous transaction which groups sequential edits to the tree into a single atomic edit if possible.\n\t * @param transaction - A callback run during the transaction to perform user-supplied operations.\n\t * It may optionally return a {@link WithValue | value }, which will be returned by the `runTransaction` call.\n\t * @param params - Optional {@link RunTransactionParams | parameters} for the transaction.\n\t * @returns A {@link TransactionResultExt | value } indicating whether or not the transaction succeeded, and containing the value returned by `transaction`.\n\t * @remarks\n\t * All of the changes in the transaction are applied synchronously and therefore no other changes from a remote client can be interleaved with those changes.\n\t * Note that this is guaranteed by Fluid for any sequence of changes that are submitted synchronously, whether in a transaction or not.\n\t *\n\t * {@link (TreeBeta:interface).on | Change events } will be emitted for changed nodes on this client _as each edit happens_, just as they would be if the changes were made outside of a transaction.\n\t * Any other/future clients or contexts will process the transaction \"squashed\", i.e. they will apply its changes all at once, emitting only a single event per node (even if that node was edited multiple times in the transaction).\n\t * Edits to the tree are not permitted within these event callbacks, therefore no other local changes from this client will be interleaved with the changes in this transaction.\n\t *\n\t * Using a transaction has the following additional consequences:\n\t *\n\t * - If {@link Revertible | reverted } (e.g. via an \"undo\" operation), all the changes in the transaction are reverted together.\n\t * Only the \"outermost\" transaction commits a change to the synchronized tree state and therefore only the outermost transaction can be reverted.\n\t * If a transaction is started and completed while another transaction is already in progress, then the inner transaction will be reverted together with the outer transaction.\n\t * - The internal data representation of a transaction with many changes is generally smaller and more efficient than that of the changes when separate.\n\t *\n\t * `runTransaction` may be invoked on the context of a {@link TreeStatus.InDocument | hydrated } or {@link Unhydrated | unhydrated } node.\n\t * Use {@link TreeContextAlpha.isBranch | isBranch() } to check whether this context is associated with a branch and gain {@link TreeBranchAlpha.(runTransaction:1) | access to more transaction capabilities} if so.\n\t */\n\trunTransaction<TValue>(\n\t\ttransaction: () => WithValue<TValue>,\n\t\tparams?: RunTransactionParams,\n\t): TransactionResultExt<TValue, TValue>;\n\n\t/** An overload of {@link TreeContextAlpha.(runTransaction:1) | runTransaction } which does not return a value. */\n\trunTransaction(transaction: () => void, params?: RunTransactionParams): TransactionResult;\n\n\t/**\n\t * An asynchronous version of {@link TreeContextAlpha.(runTransaction:1) | runTransaction}.\n\t * @remarks\n\t * As with synchronous transactions, all of the changes in an asynchronous transaction are treated as a unit.\n\t * Therefore, no other changes (either from this client or from a remote client) can be interleaved with the transaction changes.\n\t *\n\t * Unlike with synchronous transactions, it is possible that other changes (e.g. from a remote client) may be applied to the branch while this transaction is in progress.\n\t * Those other changes will be not be reflected on the branch until after this transaction completes, at which point the transaction changes will be applied after those other changes.\n\t *\n\t * An asynchronous transaction may not be started while any other transaction is in progress in this context.\n\t */\n\trunTransactionAsync<TValue>(\n\t\ttransaction: () => Promise<WithValue<TValue>>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResultExt<TValue, TValue>>;\n\n\t/** An overload of {@link TreeContextAlpha.(runTransactionAsync:1) | runTransactionAsync } which does not return a value. */\n\trunTransactionAsync(\n\t\ttransaction: () => Promise<void>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResult>;\n\n\t/**\n\t * True if this context is associated with a {@link TreeBranchAlpha | branch} and false if it is associated with an {@link Unhydrated | unhydrated } node.\n\t * @remarks If this returns true, the context can be safely inferred or cast to {@link TreeBranchAlpha} to access additional branch-specific APIs.\n\t * @example\n\t * ```typescript\n\t * const context = tree.context(someNode);\n\t * if (context.isBranch()) {\n\t * assert(context.hasRootSchema(MySchema)) // `hasRootSchema` is a method on TreeBranchAlpha, so this is only accessible if `context` is a branch context.\n\t * context.root.foo = \"bar\"; // Edit the root of the SharedTree that `someNode` belongs to.\n\t * }\n\t * ```\n\t */\n\tisBranch(): this is TreeBranchAlpha;\n}\n\n/**\n * {@link TreeBranch} with alpha-level APIs.\n * @remarks\n * The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.\n *\n * A branch does not necessarily know the schema of its SharedTree - to convert a branch to a {@link TreeViewAlpha | view with a schema}, use {@link TreeBranchAlpha.hasRootSchema | hasRootSchema()}.\n * @sealed @alpha\n */\nexport interface TreeBranchAlpha extends TreeBranch, TreeContextAlpha {\n\t/**\n\t * Events for the branch\n\t */\n\treadonly events: Listenable<TreeBranchEvents>;\n\n\t/**\n\t * Returns true if this branch has the given schema as its root schema.\n\t * @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.\n\t *\n\t * To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.\n\t * For example, a schema of `Foo | Bar` will not match a view schema of `Foo`, and likewise a schema of `Foo` will not match a view schema of `Foo | Bar`.\n\t * @example\n\t * ```typescript\n\t * if (branch.hasRootSchema(MySchema)) {\n\t * const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>\n\t * // ...\n\t * }\n\t * ```\n\t */\n\thasRootSchema<TSchema extends ImplicitFieldSchema>(\n\t\tschema: TSchema,\n\t): this is TreeViewAlpha<TSchema>;\n\n\t// Override the base fork method to return the alpha variant.\n\tfork(): TreeBranchAlpha;\n\n\t/**\n\t * {@link TreeContextAlpha.(runTransaction:1) | Run a transaction} on a branch of the SharedTree.\n\t * @param transaction - The function to run as the body of the transaction, which may optionally return a {@link TransactionCallbackStatus | value or rollback signal}.\n\t * @remarks\n\t * If the transaction is rolled back, a corresponding {@link TreeBranchEvents.changed | `changed`} event will also be emitted for the rollback.\n\t */\n\trunTransaction<TSuccessValue, TFailureValue>(\n\t\ttransaction: () => TransactionCallbackStatus<TSuccessValue, TFailureValue>,\n\t\tparams?: RunTransactionParams,\n\t): TransactionResultExt<TSuccessValue, TFailureValue>;\n\n\t/**\n\t * An overload of {@link TreeBranchAlpha.(runTransaction:1) | runTransaction } which does not return a value.\n\t */\n\trunTransaction(\n\t\ttransaction: () => VoidTransactionCallbackStatus | void,\n\t\tparams?: RunTransactionParams,\n\t): TransactionResult;\n\n\t/**\n\t * An asynchronous version of {@link TreeBranchAlpha.(runTransaction:1) | runTransaction}.\n\t * @remarks See {@link TreeContextAlpha.(runTransactionAsync:1) | runTransactionAsync} for additional information about asynchronous transactions.\n\t */\n\n\trunTransactionAsync<TSuccessValue, TFailureValue>(\n\t\ttransaction: () => Promise<TransactionCallbackStatus<TSuccessValue, TFailureValue>>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResultExt<TSuccessValue, TFailureValue>>;\n\n\t/**\n\t * An overload of {@link TreeBranchAlpha.(runTransactionAsync:1) | runTransactionAsync } which does not return a value.\n\t */\n\trunTransactionAsync(\n\t\ttransaction: () => Promise<VoidTransactionCallbackStatus | void>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResult>;\n\n\t/**\n\t * Apply a serialized change to this branch.\n\t * @param change - the change to apply.\n\t * Changes are acquired via `getChange` in a branch's {@link TreeBranchEvents.changed | \"changed\"} event.\n\t * @remarks Changes may only be applied to a SharedTree with the same IdCompressor instance and branch state from which they were generated.\n\t * They may be created by one branch and applied to another, but only if both branches share the same history at the time of creation and application.\n\t *\n\t * @privateRemarks\n\t * TODO: This method will support applying changes from different IdCompressor instances as long as they have the same local session ID.\n\t * Update the tests and docs to match when that is done.\n\t */\n\tapplyChange(change: JsonCompatibleReadOnly): void;\n}\n\n/**\n * An editable view of a (version control style) branch of a shared tree based on some schema.\n *\n * @remarks\n * This schema (known as the view schema) may or may not align with 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 {@link https://github.com/microsoft/FluidFramework/blob/main/packages/dds/tree/docs/user-facing/schema-evolution.md | schema-evolution.md}\n * and choose a schema compatibility policy that aligns with their application's needs.\n *\n * See also {@link TreeViewAlpha}, {@link TreeViewBeta} and {@link TreeBranch} for additional APIs that are in earlier stages of development.\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 *\n * @see {@link TreeViewAlpha}\n * @see {@link asTreeViewAlpha}\n *\n * @sealed @public\n */\nexport interface TreeView<in out 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 * @remarks\n\t * {@link TreeViewEvents.schemaChanged} is fired when the compatibility status changes.\n\t * See {@link https://fluidframework.com/docs/data-structures/tree/schema-evolution/ | schema-evolution} for more guidance on how to change schema while maintaining compatibility.\n\t * Use {@link snapshotSchemaCompatibility} to write tests to validate that this compatibility behaves as desired across schema changes.\n\t */\n\treadonly compatibility: SchemaCompatibilityStatus;\n\n\t/**\n\t * When {@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 * @remarks\n\t * This will update the {@link TreeView.compatibility}, allowing access to `root`.\n\t * Beware that this may impact other clients' ability to view the document: see {@link SchemaCompatibilityStatus.canView} for more information.\n\t *\n\t * It is an error to call this when {@link SchemaCompatibilityStatus.canUpgrade} is false.\n\t * {@link SchemaCompatibilityStatus.canUpgrade} being true does not mean that an upgrade is required, nor that an upgrade will have any effect.\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 * - update only a specific change (add an optional field, or apply a staged upgrade)\n\t * - update persistedMetadata or not\n\t *\n\t * As persisted metadata becomes more supported, how it interacts with isEquivalent and upgradeSchema should be clarified:\n\t * for now the docs are being left somewhat vague to allow flexibility in this area.\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\t/**\n\t * The view schema used by this TreeView.\n\t */\n\treadonly schema: TSchema;\n}\n\n/**\n * {@link TreeView} with proposed changes to the schema aware typing to allow use with `UnsafeUnknownSchema`.\n * @sealed @alpha\n */\nexport interface TreeViewAlpha<\n\tin out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,\n> extends Omit<TreeViewBeta<ReadSchema<TSchema>>, \"root\" | \"initialize\" | \"fork\">,\n\t\tTreeBranchAlpha {\n\tget root(): ReadableField<TSchema>;\n\n\tset root(newRoot: InsertableField<TSchema>);\n\n\tinitialize(content: InsertableField<TSchema>): void;\n\n\treadonly events: Listenable<TreeViewEvents & TreeBranchEvents>;\n\n\t// Override the base fork method to return a TreeViewAlpha.\n\tfork(): ReturnType<TreeBranch[\"fork\"]> & TreeViewAlpha<TSchema>;\n}\n\n/**\n * {@link TreeView} with additional beta APIs.\n * @sealed @beta\n */\nexport interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema>\n\textends TreeView<TSchema>,\n\t\tTreeBranch {\n\t// Override the base branch method to return a typed view rather than merely a branch.\n\tfork(): ReturnType<TreeBranch[\"fork\"]> & TreeViewBeta<TSchema>;\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 * @privateRemarks\n * See {@link SchemaCompatibilityTester} for the implementation of this compatibility checking.\n * @sealed @public\n */\nexport interface SchemaCompatibilityStatus {\n\t/**\n\t * Whether the view schema allows exactly the same set of documents as the stored schema.\n\t *\n\t * @remarks\n\t * Equivalence here is defined in terms of allowed documents because there are some degenerate cases where schemas are not\n\t * exact matches in a strict (schema-based) sense but still allow the same documents, and the document notion is more useful to applications.\n\t *\n\t * Examples which are expressible where this may occur include:\n\t *\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 *\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 (for example: 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\t * Note that other content in the stored schema that does not impact document compatibility, like {@link NodeSchemaOptionsAlpha.persistedMetadata}, does not affect this field.\n\t *\n\t * For the computation of this equivalence, {@link SchemaStaticsBeta.staged | staged} schemas are not included.\n\t * If there are any unknown optional fields, even if allowed by {@link ObjectSchemaOptions.allowUnknownOptionalFields}, `isEquivalent` will be false.\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 * @remarks\n\t * If the view schema does not opt into supporting any additional cases, then `canView` is only true when `isEquivalent` is also true.\n\t * The view schema can however opt into supporting additional cases, and thus can also view documents with stored schema which would be equivalent, except for the following discrepancies:\n\t *\n\t * - An object node with {@link ObjectSchemaOptions.allowUnknownOptionalFields} to set to true that has additional optional fields in the stored schema beyond those mentioned in its view schema.\n\t *\n\t * - An additional type allowed at a location in the stored schema where it is {@link SchemaStaticsBeta.staged | staged} in the view schema.\n\t *\n\t * In these cases `canUpgrade` and `isEquivalent` will be false.\n\t *\n\t * When the set of documents allowed by the view schema is a strict superset of those allowed by the stored schema,\n\t * `canView` 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 versions 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 only tolerate very specific cases beyond their schema (unknown optional fields).\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 when {@link TreeView.upgradeSchema} can add support for all content required to be supported by the view schema.\n\t * @remarks\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\t * When adding optional fields to schema which previously were marked with {@link ObjectSchemaOptions.allowUnknownOptionalFields}\n\t * the schema upgrade (assuming no other changes are included) will allow the previous version to view.\n\t * Even this case must still must be done with caution however as only clients with the newly added field will be able to do future upgrades.\n\t * Thus if a version of an application is shipped that adds an unknown optional field, all future versions should include it, even if its no longer used,\n\t * to ensure that documents containing it can still be upgraded.\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 * branch 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 TreeBranch}.\n * @sealed @alpha\n */\nexport interface TreeBranchEvents {\n\t/**\n\t * Fired when a change is made to the branch. Includes data about the change that is made which listeners\n\t * can use to filter on changes they care about (e.g. local vs. remote changes).\n\t *\n\t * @param data - information about the change\n\t * @param getRevertible - a function that allows users to get a revertible for the change. If not provided,\n\t * this change is not revertible.\n\t */\n\tchanged(data: ChangeMetadata, getRevertible?: RevertibleAlphaFactory): void;\n}\n\n/**\n * Events for {@link TreeView}.\n * @remarks\n * See {@link TreeBranchEvents} for more events related to the underlying branch of the SharedTree.\n * @sealed @public\n */\nexport interface TreeViewEvents {\n\t/**\n\t * Raised whenever {@link TreeView.root} is invalidated.\n\t *\n\t * This includes changes to the document schema.\n\t * It also includes changes to the field containing the root such as setting or clearing an optional root or changing which node is the root.\n\t * This does NOT include changes to the content (fields/children) of the root node: for that case subscribe to events on the root node.\n\t */\n\trootChanged(): void;\n\n\t/**\n\t * The stored schema for the document has changed.\n\t * This may affect the compatibility between the view schema and the stored schema, and thus the ability to use the view.\n\t *\n\t * @remarks\n\t * This event implies that the old {@link TreeView.root} is no longer valid, but applications need not handle that separately:\n\t * {@link TreeViewEvents.rootChanged} will be fired after this event.\n\t */\n\tschemaChanged(): void;\n\n\t/**\n\t * Fired when:\n\t *\n\t * - a local commit is applied outside of a transaction\n\t *\n\t * - a local transaction is committed\n\t *\n\t * The event is not fired when:\n\t *\n\t * - a local commit is applied within a transaction\n\t *\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\n/**\n * Retrieve the {@link TreeViewAlpha | alpha API} for a {@link TreeView}.\n * @alpha\n * @deprecated Use {@link (asAlpha:1)} instead.\n * @privateRemarks Despite being deprecated, this function should be used within the tree package (outside of tests) rather than `asAlpha` in order to avoid circular import dependencies.\n */\nexport function asTreeViewAlpha<TSchema extends ImplicitFieldSchema>(\n\tview: TreeView<TSchema>,\n): TreeViewAlpha<TSchema> {\n\treturn view as TreeViewAlpha<TSchema>;\n}\n"]}
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../../src/simple-tree/api/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAunBH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC9B,IAAuB;IAEvB,OAAO,IAA8B,CAAC;AACvC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IFluidLoadable, IDisposable, Listenable } from \"@fluidframework/core-interfaces\";\n\nimport type {\n\tChangeMetadata,\n\tCommitMetadata,\n\tRevertibleAlphaFactory,\n\tRevertibleFactory,\n} from \"../../core/index.js\";\n// This is referenced by doc comments.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { TreeStatus } from \"../../feature-libraries/index.js\";\nimport type {\n\t// This is referenced by doc comments.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports\n\tTreeAlpha,\n} from \"../../shared-tree/index.js\";\nimport type { JsonCompatibleReadOnly } from \"../../util/index.js\";\n// This is referenced by doc comments.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { Unhydrated } from \"../core/index.js\";\nimport type {\n\tImplicitFieldSchema,\n\tInsertableField,\n\tInsertableTreeFieldFromImplicitField,\n\tReadableField,\n\tReadSchema,\n\tTreeFieldFromImplicitField,\n} from \"../fieldSchema.js\";\nimport type { SimpleTreeSchema } from \"../simpleSchema.js\";\nimport type { UnsafeUnknownSchema } from \"../unsafeUnknownSchema.js\";\n\nimport type { TreeViewConfiguration } from \"./configuration.js\";\nimport type {\n\tRunTransactionParams,\n\tTransactionCallbackStatus,\n\tTransactionResult,\n\tTransactionResultExt,\n\tVoidTransactionCallbackStatus,\n\tWithValue,\n} from \"./transactionTypes.js\";\nimport type { VerboseTree } from \"./verboseTree.js\";\n\n/**\n * A tree from which a {@link TreeView} can be created.\n *\n * @privateRemarks\n * TODO:\n * Add stored key versions of {@link (TreeAlpha:interface).(exportVerbose:2)}, {@link (TreeAlpha:interface).(exportConcise:2)} and {@link (TreeAlpha:interface).exportCompressed} here so tree content can be accessed without a view schema.\n * Add exportSimpleSchema and exportJsonSchema methods (which should exactly match the concise format, and match the free functions for exporting view schema).\n * Maybe rename \"exportJsonSchema\" to align on \"concise\" terminology.\n * Ensure schema exporting APIs here align and reference APIs for exporting view schema to the same formats (which should include stored vs property key choice).\n * Make sure users of independentView can use these export APIs (maybe provide a reference back to the ViewableTree from the TreeView to accomplish that).\n * @system @sealed @public\n */\nexport interface ViewableTree {\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: Support adapters for handling out-of-schema data.\n\t */\n\tviewWith<TRoot extends ImplicitFieldSchema>(\n\t\tconfig: TreeViewConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * Channel for a Fluid Tree DDS.\n * @remarks\n * Allows storing and collaboratively editing schema-aware hierarchial data.\n * @sealed @public\n */\nexport interface ITree extends ViewableTree, IFluidLoadable {}\n\n/**\n * {@link ITree} extended with some alpha APIs.\n * @sealed @alpha\n */\nexport interface ITreeAlpha extends ITree {\n\t/**\n\t * Exports root in the same format as {@link (TreeAlpha:interface).(exportVerbose:1)} using stored keys.\n\t * @remarks\n\t * This is `undefined` if and only if the root field is empty (this can only happen if the root field is optional).\n\t */\n\texportVerbose(): VerboseTree | undefined;\n\n\t/**\n\t * Exports the SimpleTreeSchema that is stored in the tree, using stored keys for object fields.\n\t * @remarks\n\t * To get the schema using property keys, use {@link getSimpleSchema} on the view schema.\n\t */\n\texportSimpleSchema(): SimpleTreeSchema;\n\n\t/**\n\t * Creates a fork of the current state of the main branch.\n\t * This new branch will be shared with and editable by all clients.\n\t */\n\tcreateSharedBranch(): string;\n\n\t/**\n\t * Returns a list of all shared branches that currently exist on this tree.\n\t * Any one of them can be checked out using {@link ITreeAlpha.viewSharedBranchWith}.\n\t */\n\tgetSharedBranchIds(): string[];\n\n\t/**\n\t * Returns a view of the tree on the specified shared branch, using the provided schema.\n\t * See {@link ViewableTree.viewWith}.\n\t */\n\tviewSharedBranchWith<TRoot extends ImplicitFieldSchema>(\n\t\tbranchId: string,\n\t\tconfig: TreeViewConfiguration<TRoot>,\n\t): TreeView<TRoot>;\n}\n\n/**\n * A collection of functionality associated with a (version-control-style) branch of a SharedTree.\n * @remarks A `TreeBranch` allows for the {@link TreeBranch.fork | creation of branches} and for those branches to later be {@link TreeBranch.merge | merged}.\n *\n * The branch associated directly with the {@link ITree | SharedTree} is the \"main\" branch, and all other branches fork (directly or transitively) from that main branch.\n *\n * See {@link TreeBranchAlpha} for additional APIs that are in an earlier stage of development.\n * @sealed @beta\n */\nexport interface TreeBranch extends IDisposable {\n\t/**\n\t * Fork a new branch off of this branch which is based off of this branch's current state.\n\t * @remarks Any changes to the tree on the new branch will not apply to this branch until the new branch is e.g. {@link TreeBranch.merge | merged} back into this branch.\n\t * The branch should be disposed when no longer needed, either {@link TreeBranch.dispose | explicitly} or {@link TreeBranch.merge | implicitly when merging} into another branch.\n\t */\n\tfork(): TreeBranch;\n\n\t/**\n\t * Apply all the new changes on the given branch to this branch.\n\t * @param branch - a branch which was created by a call to `branch()`.\n\t * @param disposeMerged - whether or not to dispose `branch` after the merge completes.\n\t * Defaults to true.\n\t * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.\n\t * @remarks All ongoing transactions (if any) in `branch` will be committed before the merge.\n\t */\n\tmerge(branch: TreeBranch, disposeMerged?: boolean): void;\n\n\t/**\n\t * Advance this branch forward such that all new changes on the target branch become part of this branch.\n\t * @param branch - The branch to rebase onto.\n\t * @remarks After rebasing, this branch will be \"ahead\" of the target branch, that is, its unique changes will have been recreated as if they happened after all changes on the target branch.\n\t * This method may only be called on branches produced via {@link TreeBranch.fork | branch} - attempting to rebase the main branch will throw.\n\t *\n\t * Rebasing long-lived branches is important to avoid consuming memory unnecessarily.\n\t * In particular, the SharedTree retains all sequenced changes made to the tree since the \"most-behind\" branch was created or last rebased.\n\t *\n\t * The {@link TreeBranch | main branch} cannot be rebased onto another branch - attempting to do so will throw an error.\n\t */\n\trebaseOnto(branch: TreeBranch): void;\n\n\t/**\n\t * Dispose of this branch, cleaning up any resources associated with it.\n\t * @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.\n\t * @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.\n\t *\n\t * Disposing branches is important to avoid consuming memory unnecessarily.\n\t * In particular, the SharedTree retains all sequenced changes made to the tree since the \"most-behind\" branch was created or last {@link TreeBranch.rebaseOnto | rebased}.\n\t *\n\t * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.\n\t */\n\tdispose(error?: Error): void;\n}\n\n/**\n * Provides additional APIs that may be used to interact with a tree node or a tree node's SharedTree.\n * @alpha\n */\nexport interface TreeContextAlpha {\n\t/**\n\t * Run a synchronous transaction which groups sequential edits to the tree into a single atomic edit if possible.\n\t * @param transaction - A callback run during the transaction to perform user-supplied operations.\n\t * It may optionally return a {@link WithValue | value }, which will be returned by the `runTransaction` call.\n\t * @param params - Optional {@link RunTransactionParams | parameters} for the transaction.\n\t * @returns A {@link TransactionResultExt | value } indicating whether or not the transaction succeeded, and containing the value returned by `transaction`.\n\t * @remarks\n\t * All of the changes in the transaction are applied synchronously and therefore no other changes from a remote client can be interleaved with those changes.\n\t * Note that this is guaranteed by Fluid for any sequence of changes that are submitted synchronously, whether in a transaction or not.\n\t *\n\t * {@link (TreeBeta:interface).on | Change events } will be emitted for changed nodes on this client _as each edit happens_, just as they would be if the changes were made outside of a transaction.\n\t * Any other/future clients or contexts will process the transaction \"squashed\", i.e. they will apply its changes all at once, emitting only a single event per node (even if that node was edited multiple times in the transaction).\n\t * Edits to the tree are not permitted within these event callbacks, therefore no other local changes from this client will be interleaved with the changes in this transaction.\n\t *\n\t * Using a transaction has the following additional consequences:\n\t *\n\t * - If {@link Revertible | reverted } (e.g. via an \"undo\" operation), all the changes in the transaction are reverted together.\n\t * Only the \"outermost\" transaction commits a change to the synchronized tree state and therefore only the outermost transaction can be reverted.\n\t * If a transaction is started and completed while another transaction is already in progress, then the inner transaction will be reverted together with the outer transaction.\n\t * - The internal data representation of a transaction with many changes is generally smaller and more efficient than that of the changes when separate.\n\t *\n\t * `runTransaction` may be invoked on the context of a {@link TreeStatus.InDocument | hydrated } or {@link Unhydrated | unhydrated } node.\n\t * Use {@link TreeContextAlpha.isBranch | isBranch() } to check whether this context is associated with a branch and gain {@link TreeBranchAlpha.(runTransaction:1) | access to more transaction capabilities} if so.\n\t */\n\trunTransaction<TValue>(\n\t\ttransaction: () => WithValue<TValue>,\n\t\tparams?: RunTransactionParams,\n\t): TransactionResultExt<TValue, TValue>;\n\n\t/** An overload of {@link TreeContextAlpha.(runTransaction:1) | runTransaction } which does not return a value. */\n\trunTransaction(transaction: () => void, params?: RunTransactionParams): TransactionResult;\n\n\t/**\n\t * An asynchronous version of {@link TreeContextAlpha.(runTransaction:1) | runTransaction}.\n\t * @remarks\n\t * As with synchronous transactions, all of the changes in an asynchronous transaction are treated as a unit.\n\t * Therefore, no other changes (either from this client or from a remote client) can be interleaved with the transaction changes.\n\t *\n\t * Unlike with synchronous transactions, it is possible that other changes (e.g. from a remote client) may be applied to the branch while this transaction is in progress.\n\t * Those other changes will be not be reflected on the branch until after this transaction completes, at which point the transaction changes will be applied after those other changes.\n\t *\n\t * An asynchronous transaction may not be started while any other transaction is in progress in this context.\n\t */\n\trunTransactionAsync<TValue>(\n\t\ttransaction: () => Promise<WithValue<TValue>>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResultExt<TValue, TValue>>;\n\n\t/** An overload of {@link TreeContextAlpha.(runTransactionAsync:1) | runTransactionAsync } which does not return a value. */\n\trunTransactionAsync(\n\t\ttransaction: () => Promise<void>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResult>;\n\n\t/**\n\t * True if this context is associated with a {@link TreeBranchAlpha | branch} and false if it is associated with an {@link Unhydrated | unhydrated } node.\n\t * @remarks If this returns true, the context can be safely inferred or cast to {@link TreeBranchAlpha} to access additional branch-specific APIs.\n\t * @example\n\t * ```typescript\n\t * const context = tree.context(someNode);\n\t * if (context.isBranch()) {\n\t * assert(context.hasRootSchema(MySchema)) // `hasRootSchema` is a method on TreeBranchAlpha, so this is only accessible if `context` is a branch context.\n\t * context.root.foo = \"bar\"; // Edit the root of the SharedTree that `someNode` belongs to.\n\t * }\n\t * ```\n\t */\n\tisBranch(): this is TreeBranchAlpha;\n}\n\n/**\n * {@link TreeBranch} with alpha-level APIs.\n * @remarks\n * The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.\n *\n * A branch does not necessarily know the schema of its SharedTree - to convert a branch to a {@link TreeViewAlpha | view with a schema}, use {@link TreeBranchAlpha.hasRootSchema | hasRootSchema()}.\n * @sealed @alpha\n */\nexport interface TreeBranchAlpha extends TreeBranch, TreeContextAlpha {\n\t/**\n\t * Events for the branch\n\t */\n\treadonly events: Listenable<TreeBranchEvents>;\n\n\t/**\n\t * Returns true if this branch has the given schema as its root schema.\n\t * @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.\n\t *\n\t * To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.\n\t * For example, a schema of `Foo | Bar` will not match a view schema of `Foo`, and likewise a schema of `Foo` will not match a view schema of `Foo | Bar`.\n\t * @example\n\t * ```typescript\n\t * if (branch.hasRootSchema(MySchema)) {\n\t * const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>\n\t * // ...\n\t * }\n\t * ```\n\t */\n\thasRootSchema<TSchema extends ImplicitFieldSchema>(\n\t\tschema: TSchema,\n\t): this is TreeViewAlpha<TSchema>;\n\n\t// Override the base fork method to return the alpha variant.\n\tfork(): TreeBranchAlpha;\n\n\t/**\n\t * {@link TreeContextAlpha.(runTransaction:1) | Run a transaction} on a branch of the SharedTree.\n\t * @param transaction - The function to run as the body of the transaction, which may optionally return a {@link TransactionCallbackStatus | value or rollback signal}.\n\t * @remarks\n\t * If the transaction is rolled back, a corresponding {@link TreeBranchEvents.changed | `changed`} event will also be emitted for the rollback.\n\t */\n\trunTransaction<TSuccessValue, TFailureValue>(\n\t\ttransaction: () => TransactionCallbackStatus<TSuccessValue, TFailureValue>,\n\t\tparams?: RunTransactionParams,\n\t): TransactionResultExt<TSuccessValue, TFailureValue>;\n\n\t/**\n\t * An overload of {@link TreeBranchAlpha.(runTransaction:1) | runTransaction } which does not return a value.\n\t */\n\trunTransaction(\n\t\ttransaction: () => VoidTransactionCallbackStatus | void,\n\t\tparams?: RunTransactionParams,\n\t): TransactionResult;\n\n\t/**\n\t * An asynchronous version of {@link TreeBranchAlpha.(runTransaction:1) | runTransaction}.\n\t * @remarks See {@link TreeContextAlpha.(runTransactionAsync:1) | runTransactionAsync} for additional information about asynchronous transactions.\n\t */\n\n\trunTransactionAsync<TSuccessValue, TFailureValue>(\n\t\ttransaction: () => Promise<TransactionCallbackStatus<TSuccessValue, TFailureValue>>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResultExt<TSuccessValue, TFailureValue>>;\n\n\t/**\n\t * An overload of {@link TreeBranchAlpha.(runTransactionAsync:1) | runTransactionAsync } which does not return a value.\n\t */\n\trunTransactionAsync(\n\t\ttransaction: () => Promise<VoidTransactionCallbackStatus | void>,\n\t\tparams?: RunTransactionParams,\n\t): Promise<TransactionResult>;\n\n\t/**\n\t * Apply a serialized change to this branch.\n\t * @param change - the change to apply.\n\t * Changes are acquired via `getChange` in a branch's {@link TreeBranchEvents.changed | \"changed\"} event.\n\t * @remarks Changes may only be applied to a SharedTree with the same IdCompressor instance and branch state from which they were generated.\n\t * They may be created by one branch and applied to another, but only if both branches share the same history at the time of creation and application.\n\t *\n\t * @privateRemarks\n\t * TODO: This method will support applying changes from different IdCompressor instances as long as they have the same local session ID.\n\t * Update the tests and docs to match when that is done.\n\t */\n\tapplyChange(change: JsonCompatibleReadOnly): void;\n\n\t/**\n\t * Determines if there are changes on the given branch that are not present on this branch.\n\t * @param branch - The branch to compare to.\n\t *\n\t * The new edits, if any, can be applied to this branch by {@link TreeBranch.rebaseOnto | rebasing this branch onto the given branch}\n\t * or by {@link TreeBranch.merge | merging the given branch into this branch}.\n\t *\n\t * @throws UsageError if the branches are unrelated.\n\t */\n\tisMissingEditsFrom(branch: TreeBranch): boolean;\n}\n\n/**\n * An editable view of a (version control style) branch of a shared tree based on some schema.\n *\n * @remarks\n * This schema (known as the view schema) may or may not align with 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 {@link https://github.com/microsoft/FluidFramework/blob/main/packages/dds/tree/docs/user-facing/schema-evolution.md | schema-evolution.md}\n * and choose a schema compatibility policy that aligns with their application's needs.\n *\n * See also {@link TreeViewAlpha}, {@link TreeViewBeta} and {@link TreeBranch} for additional APIs that are in earlier stages of development.\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 *\n * @see {@link TreeViewAlpha}\n * @see {@link asTreeViewAlpha}\n *\n * @sealed @public\n */\nexport interface TreeView<in out 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 * @remarks\n\t * {@link TreeViewEvents.schemaChanged} is fired when the compatibility status changes.\n\t * See {@link https://fluidframework.com/docs/data-structures/tree/schema-evolution/ | schema-evolution} for more guidance on how to change schema while maintaining compatibility.\n\t * Use {@link snapshotSchemaCompatibility} to write tests to validate that this compatibility behaves as desired across schema changes.\n\t */\n\treadonly compatibility: SchemaCompatibilityStatus;\n\n\t/**\n\t * When {@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 * @remarks\n\t * This will update the {@link TreeView.compatibility}, allowing access to `root`.\n\t * Beware that this may impact other clients' ability to view the document: see {@link SchemaCompatibilityStatus.canView} for more information.\n\t *\n\t * It is an error to call this when {@link SchemaCompatibilityStatus.canUpgrade} is false.\n\t * {@link SchemaCompatibilityStatus.canUpgrade} being true does not mean that an upgrade is required, nor that an upgrade will have any effect.\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 * - update only a specific change (add an optional field, or apply a staged upgrade)\n\t * - update persistedMetadata or not\n\t *\n\t * As persisted metadata becomes more supported, how it interacts with isEquivalent and upgradeSchema should be clarified:\n\t * for now the docs are being left somewhat vague to allow flexibility in this area.\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\t/**\n\t * The view schema used by this TreeView.\n\t */\n\treadonly schema: TSchema;\n}\n\n/**\n * {@link TreeView} with proposed changes to the schema aware typing to allow use with `UnsafeUnknownSchema`.\n * @sealed @alpha\n */\nexport interface TreeViewAlpha<\n\tin out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,\n> extends Omit<TreeViewBeta<ReadSchema<TSchema>>, \"root\" | \"initialize\" | \"fork\">,\n\t\tTreeBranchAlpha {\n\tget root(): ReadableField<TSchema>;\n\n\tset root(newRoot: InsertableField<TSchema>);\n\n\tinitialize(content: InsertableField<TSchema>): void;\n\n\treadonly events: Listenable<TreeViewEvents & TreeBranchEvents>;\n\n\t// Override the base fork method to return a TreeViewAlpha.\n\tfork(): ReturnType<TreeBranch[\"fork\"]> & TreeViewAlpha<TSchema>;\n}\n\n/**\n * {@link TreeView} with additional beta APIs.\n * @sealed @beta\n */\nexport interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema>\n\textends TreeView<TSchema>,\n\t\tTreeBranch {\n\t// Override the base branch method to return a typed view rather than merely a branch.\n\tfork(): ReturnType<TreeBranch[\"fork\"]> & TreeViewBeta<TSchema>;\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 * @privateRemarks\n * See {@link SchemaCompatibilityTester} for the implementation of this compatibility checking.\n * @sealed @public\n */\nexport interface SchemaCompatibilityStatus {\n\t/**\n\t * Whether the view schema allows exactly the same set of documents as the stored schema.\n\t *\n\t * @remarks\n\t * Equivalence here is defined in terms of allowed documents because there are some degenerate cases where schemas are not\n\t * exact matches in a strict (schema-based) sense but still allow the same documents, and the document notion is more useful to applications.\n\t *\n\t * Examples which are expressible where this may occur include:\n\t *\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 *\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 (for example: 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\t * Note that other content in the stored schema that does not impact document compatibility, like {@link NodeSchemaOptionsAlpha.persistedMetadata}, does not affect this field.\n\t *\n\t * For the computation of this equivalence, {@link SchemaStaticsBeta.staged | staged} schemas are not included.\n\t * If there are any unknown optional fields, even if allowed by {@link ObjectSchemaOptions.allowUnknownOptionalFields}, `isEquivalent` will be false.\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 * @remarks\n\t * If the view schema does not opt into supporting any additional cases, then `canView` is only true when `isEquivalent` is also true.\n\t * The view schema can however opt into supporting additional cases, and thus can also view documents with stored schema which would be equivalent, except for the following discrepancies:\n\t *\n\t * - An object node with {@link ObjectSchemaOptions.allowUnknownOptionalFields} to set to true that has additional optional fields in the stored schema beyond those mentioned in its view schema.\n\t *\n\t * - An additional type allowed at a location in the stored schema where it is {@link SchemaStaticsBeta.staged | staged} in the view schema.\n\t *\n\t * In these cases `canUpgrade` and `isEquivalent` will be false.\n\t *\n\t * When the set of documents allowed by the view schema is a strict superset of those allowed by the stored schema,\n\t * `canView` 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 versions 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 only tolerate very specific cases beyond their schema (unknown optional fields).\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 when {@link TreeView.upgradeSchema} can add support for all content required to be supported by the view schema.\n\t * @remarks\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\t * When adding optional fields to schema which previously were marked with {@link ObjectSchemaOptions.allowUnknownOptionalFields}\n\t * the schema upgrade (assuming no other changes are included) will allow the previous version to view.\n\t * Even this case must still must be done with caution however as only clients with the newly added field will be able to do future upgrades.\n\t * Thus if a version of an application is shipped that adds an unknown optional field, all future versions should include it, even if its no longer used,\n\t * to ensure that documents containing it can still be upgraded.\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 * branch 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 TreeBranch}.\n * @sealed @alpha\n */\nexport interface TreeBranchEvents {\n\t/**\n\t * Fired when a change is made to the branch. Includes data about the change that is made which listeners\n\t * can use to filter on changes they care about (e.g. local vs. remote changes).\n\t *\n\t * @param data - information about the change\n\t * @param getRevertible - a function that allows users to get a revertible for the change. If not provided,\n\t * this change is not revertible.\n\t */\n\tchanged(data: ChangeMetadata, getRevertible?: RevertibleAlphaFactory): void;\n}\n\n/**\n * Events for {@link TreeView}.\n * @remarks\n * See {@link TreeBranchEvents} for more events related to the underlying branch of the SharedTree.\n * @sealed @public\n */\nexport interface TreeViewEvents {\n\t/**\n\t * Raised whenever {@link TreeView.root} is invalidated.\n\t *\n\t * This includes changes to the document schema.\n\t * It also includes changes to the field containing the root such as setting or clearing an optional root or changing which node is the root.\n\t * This does NOT include changes to the content (fields/children) of the root node: for that case subscribe to events on the root node.\n\t */\n\trootChanged(): void;\n\n\t/**\n\t * The stored schema for the document has changed.\n\t * This may affect the compatibility between the view schema and the stored schema, and thus the ability to use the view.\n\t *\n\t * @remarks\n\t * This event implies that the old {@link TreeView.root} is no longer valid, but applications need not handle that separately:\n\t * {@link TreeViewEvents.rootChanged} will be fired after this event.\n\t */\n\tschemaChanged(): void;\n\n\t/**\n\t * Fired when:\n\t *\n\t * - a local commit is applied outside of a transaction\n\t *\n\t * - a local transaction is committed\n\t *\n\t * The event is not fired when:\n\t *\n\t * - a local commit is applied within a transaction\n\t *\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\n/**\n * Retrieve the {@link TreeViewAlpha | alpha API} for a {@link TreeView}.\n * @alpha\n * @deprecated Use {@link (asAlpha:1)} instead.\n * @privateRemarks Despite being deprecated, this function should be used within the tree package (outside of tests) rather than `asAlpha` in order to avoid circular import dependencies.\n */\nexport function asTreeViewAlpha<TSchema extends ImplicitFieldSchema>(\n\tview: TreeView<TSchema>,\n): TreeViewAlpha<TSchema> {\n\treturn view as TreeViewAlpha<TSchema>;\n}\n"]}
@@ -2,18 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
6
- if (kind === "m") throw new TypeError("Private method is not writable");
7
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
8
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
9
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
10
- };
11
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
13
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
14
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
- };
16
5
  var _TreeNodeKernel_hydrationState, _TreeNodeKernel_eventBuffer, _KernelEventBuffer_instances, _KernelEventBuffer_disposed, _KernelEventBuffer_events, _KernelEventBuffer_eventSource, _KernelEventBuffer_disposeSourceListeners, _KernelEventBuffer_childrenChangedBuffer, _KernelEventBuffer_fieldMarksBuffer, _KernelEventBuffer_invalidatedFieldMarkKeys, _KernelEventBuffer_subTreeChangedBuffer, _KernelEventBuffer_emit, _KernelEventBuffer_handleChildrenChangedAfterBatch, _KernelEventBuffer_handleSubtreeChangedAfterBatch, _KernelEventBuffer_assertNotDisposed;
6
+ import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
17
7
  import { createEmitter } from "@fluid-internal/client-utils";
18
8
  import { assert, fail, debugAssert, unreachableCase, } from "@fluidframework/core-utils/internal";
19
9
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
@@ -1 +1 @@
1
- {"version":3,"file":"treeNodeKernel.js","sourceRoot":"","sources":["../../../src/simple-tree/core/treeNodeKernel.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 { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { HasListeners, Listenable, Off } from \"@fluidframework/core-interfaces/internal\";\nimport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tunreachableCase,\n} from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tanchorSlot,\n\ttype AnchorEvents,\n\ttype AnchorNode,\n\ttype DeltaMark,\n\ttype FieldKey,\n\ttype TreeValue,\n} from \"../../core/index.js\";\nimport { getOrCreateHydratedFlexTreeNode } from \"../../feature-libraries/index.js\";\nimport {\n\tContextSlot,\n\tflexTreeSlot,\n\tLazyEntity,\n\tTreeStatus,\n\ttreeStatusFromAnchorCache,\n\ttype FlexTreeNode,\n\ttype HydratedFlexTreeNode,\n} from \"../../feature-libraries/index.js\";\n\nimport type { Context, HydratedContext } from \"./context.js\";\nimport type { TreeNode } from \"./treeNode.js\";\nimport type { TreeNodeSchema } from \"./treeNodeSchema.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport { UnhydratedFlexTreeNode } from \"./unhydratedFlexTree.js\";\n\nconst treeNodeToKernel = new WeakMap<TreeNode, TreeNodeKernel>();\n\nexport function getKernel(node: TreeNode): TreeNodeKernel {\n\tconst kernel = treeNodeToKernel.get(node);\n\tassert(kernel !== undefined, 0x9b1 /* Expected tree node to have kernel */);\n\treturn kernel;\n}\n\n/**\n * Detects if the given 'candidate' is a TreeNode.\n *\n * @remarks\n * Supports both Hydrated and {@link Unhydrated} TreeNodes, both of which return true.\n *\n * Because the common usage is to check if a value being inserted/set is a TreeNode,\n * this function permits calling with primitives as well as objects.\n *\n * Primitives will always return false (as they are copies of data, not references to nodes).\n *\n * @param candidate - Value which may be a TreeNode\n * @returns true if the given 'candidate' is a hydrated TreeNode.\n */\nexport function isTreeNode(candidate: unknown): candidate is TreeNode | Unhydrated<TreeNode> {\n\treturn treeNodeToKernel.has(candidate as TreeNode);\n}\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode}.\n *\n * Returns undefined for other values.\n * @remarks\n * Does not give schema for a {@link TreeLeafValue}.\n */\nexport function tryGetTreeNodeSchema(value: unknown): undefined | TreeNodeSchema {\n\tconst kernel = treeNodeToKernel.get(value as TreeNode);\n\treturn kernel?.schema;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} before the kernel is hydrated */\ninterface UnhydratedState {\n\treadonly innerNode: UnhydratedFlexTreeNode;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} after the kernel is hydrated */\ninterface HydratedState {\n\t/** The flex node for this kernel */\n\treadonly innerNode: HydratedFlexTreeNode;\n\t/** All {@link Off | event deregistration functions} that should be run when the kernel is disposed. */\n\treadonly offAnchorNode: Set<Off>;\n}\n\n/** State within a {@link TreeNodeKernel} that is related to the hydration process */\ntype HydrationState = UnhydratedState | HydratedState;\n\n/** True if and only if the given {@link HydrationState} is post-hydration */\nfunction isHydrated(state: HydrationState): state is HydratedState {\n\treturn state.innerNode.isHydrated();\n}\n\n/**\n * Contains state and an internal API for managing {@link TreeNode}s.\n * @remarks All {@link TreeNode}s have an associated kernel object.\n * The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.\n */\nexport class TreeNodeKernel {\n\tprivate disposed = false;\n\n\t/**\n\t * Generation number which is incremented any time we have an edit on the node.\n\t * Used during iteration to make sure there has been no edits that were concurrently made.\n\t * @remarks\n\t * This is updated monotonically by this class when edits are applied.\n\t * TODO: update this when applying edits to unhydrated trees.\n\t *\n\t * If TypeScript supported making this immutable from outside the class without making it readonly from inside, that would be used here,\n\t * but they only way to do that is add a separate public accessor and make it private, which was deemed not worth the boilerplate, runtime overhead and bundle size.\n\t */\n\tpublic generationNumber: number = 0;\n\n\t#hydrationState: HydrationState;\n\n\t/**\n\t * Handler for events listeners registered with the kernel.\n\t *\n\t * @remarks\n\t * Supports event buffering via {@link withBufferedEvents}.\n\t *\n\t * Allocated lazily on first access to {@link TreeNodeKernel.events}.\n\t * We expect the majority of nodes to never have event listeners registered, so\n\t * deferring construction avoids per-kernel allocations.\n\t */\n\t#eventBuffer: KernelEventBuffer | undefined;\n\n\t/**\n\t * Create a TreeNodeKernel which can be looked up with {@link getKernel}.\n\t *\n\t * @param initialContext - context from when this node was originally created. Only used when unhydrated.\n\t * @param innerNode - When unhydrated the MapTreeNode. Otherwise HydratedFlexTreeNode.\n\t * @remarks\n\t * Exactly one kernel per TreeNode should be created.\n\t */\n\tpublic constructor(\n\t\tpublic readonly node: TreeNode,\n\t\tpublic readonly schema: TreeNodeSchema,\n\t\tinnerNode: InnerNode,\n\t\tprivate readonly initialContext: Context,\n\t) {\n\t\tsplitInnerNodeType(innerNode);\n\n\t\tassert(!treeNodeToKernel.has(node), 0xa1a /* only one kernel per node can be made */);\n\t\ttreeNodeToKernel.set(node, this);\n\n\t\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\t\t// Unhydrated case\n\n\t\t\tdebugAssert(() => innerNode.treeNode === undefined);\n\t\t\tinnerNode.treeNode = node;\n\n\t\t\tthis.#hydrationState = {\n\t\t\t\tinnerNode,\n\t\t\t};\n\t\t} else {\n\t\t\t// Hydrated case\n\t\t\tthis.#hydrationState = this.createHydratedState(innerNode);\n\t\t}\n\t}\n\n\tpublic get context(): Context {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\t// This can't be cached on this.#hydrated during hydration since initial tree is hydrated before the context is cached on the anchorSet.\n\t\t\treturn (\n\t\t\t\tthis.#hydrationState.innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot) ??\n\t\t\t\tfail(0xb40 /* missing simple-tree context */)\n\t\t\t);\n\t\t}\n\t\treturn this.initialContext;\n\t}\n\n\t/**\n\t * Transition from {@link Unhydrated} to hydrated.\n\t * Bi-directionally associates the given hydrated TreeNode to the HydratedFlexTreeNode.\n\t * @remarks\n\t * Happens at most once for any given node.\n\t * Cleans up mappings to {@link UnhydratedFlexTreeNode} - it is assumed that they are no longer needed once this node has an anchor node.\n\t */\n\tpublic hydrate(inner: HydratedFlexTreeNode): void {\n\t\tassert(!this.disposed, 0xa2a /* cannot hydrate a disposed node */);\n\t\tassert(!isHydrated(this.#hydrationState), 0xa2b /* hydration should only happen once */);\n\n\t\tthis.#hydrationState = this.createHydratedState(inner);\n\n\t\t// Lazily migrate existing event listeners to the anchor node.\n\t\t// If no one ever subscribed to this kernel's events, the buffer was never allocated\n\t\t// and there is nothing to migrate.\n\t\tthis.#eventBuffer?.migrateEventSource(inner.anchorNode.events);\n\t}\n\n\tprivate createHydratedState(innerNode: HydratedFlexTreeNode): HydratedState {\n\t\tassert(\n\t\t\t!innerNode.anchorNode.slots.has(simpleTreeNodeSlot),\n\t\t\t0x7f5 /* Cannot associate an flex node with multiple simple-tree nodes */,\n\t\t);\n\t\tinnerNode.anchorNode.slots.set(simpleTreeNodeSlot, this.node);\n\t\treturn {\n\t\t\tinnerNode,\n\t\t\toffAnchorNode: new Set([\n\t\t\t\tinnerNode.anchorNode.events.on(\"afterDestroy\", () => this.dispose()),\n\t\t\t\t// TODO: this should be triggered on change even for unhydrated nodes.\n\t\t\t\tinnerNode.anchorNode.events.on(\"childrenChanging\", () => {\n\t\t\t\t\tthis.generationNumber += 1;\n\t\t\t\t}),\n\t\t\t]),\n\t\t};\n\t}\n\n\tpublic getStatus(): TreeStatus {\n\t\tif (this.disposed) {\n\t\t\treturn TreeStatus.Deleted;\n\t\t}\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\treturn TreeStatus.New;\n\t\t}\n\n\t\t// TODO: Replace this check with the proper check against the cursor state when the cursor becomes part of the kernel\n\t\tconst flex = this.#hydrationState.innerNode.anchorNode.slots.get(flexTreeSlot);\n\t\tif (flex !== undefined) {\n\t\t\tassert(flex instanceof LazyEntity, 0x9b4 /* Unexpected flex node implementation */);\n\t\t\tif (flex.isFreed()) {\n\t\t\t\treturn TreeStatus.Deleted;\n\t\t\t}\n\t\t}\n\n\t\treturn treeStatusFromAnchorCache(this.#hydrationState.innerNode.anchorNode);\n\t}\n\n\tpublic get events(): Listenable<KernelEvents> {\n\t\tassert(!this.disposed, 0xcfa /* Cannot register events on a disposed node */);\n\t\t// Allocate the buffer on first access. See {@link TreeNodeKernel.#eventBuffer} for rationale.\n\t\tif (this.#eventBuffer === undefined) {\n\t\t\tconst eventSource = isHydrated(this.#hydrationState)\n\t\t\t\t? this.#hydrationState.innerNode.anchorNode.events\n\t\t\t\t: this.#hydrationState.innerNode.events;\n\t\t\tthis.#eventBuffer = new KernelEventBuffer(eventSource);\n\t\t}\n\t\treturn this.#eventBuffer;\n\t}\n\n\tpublic dispose(): void {\n\t\tdebugAssert(() => !this.disposed || \"Cannot dispose a disposed node\");\n\t\tthis.disposed = true;\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\tfor (const off of this.#hydrationState.offAnchorNode) {\n\t\t\t\toff();\n\t\t\t}\n\t\t}\n\t\tthis.#eventBuffer?.dispose();\n\t\t// TODO: go to the context and remove myself from withAnchors\n\t}\n\n\tpublic isHydrated(): this is { anchorNode: AnchorNode; context: HydratedContext } {\n\t\treturn isHydrated(this.#hydrationState);\n\t}\n\n\tpublic get anchorNode(): AnchorNode | undefined {\n\t\treturn isHydrated(this.#hydrationState)\n\t\t\t? this.#hydrationState.innerNode.anchorNode\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Retrieves the flex node associated with the given target.\n\t * @remarks\n\t * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n\t *\n\t * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n\t */\n\tpublic getInnerNode(): InnerNode {\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\tdebugAssert(\n\t\t\t\t() =>\n\t\t\t\t\tthis.#hydrationState.innerNode?.context.isDisposed() === false ||\n\t\t\t\t\t\"Unhydrated node should never be disposed\",\n\t\t\t);\n\t\t\treturn this.#hydrationState.innerNode; // Unhydrated case\n\t\t}\n\n\t\tif (this.disposed) {\n\t\t\tthrow new UsageError(\"Cannot access a deleted node.\");\n\t\t}\n\n\t\treturn this.#hydrationState.innerNode;\n\t}\n\n\t/**\n\t * Retrieves the {@link UnhydratedFlexTreeNode} if unhydrated. otherwise undefined.\n\t */\n\tpublic getInnerNodeIfUnhydrated(): UnhydratedFlexTreeNode | undefined {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.#hydrationState.innerNode;\n\t}\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst kernelEvents = [\"childrenChangedAfterBatch\", \"subtreeChangedAfterBatch\"] as const;\n\ntype KernelEvents = Pick<AnchorEvents, (typeof kernelEvents)[number]>;\n\n// #region TreeNodeEventBuffer\n\n/**\n * Whether or not events from {@link TreeNodeKernel} should be buffered instead of emitted immediately.\n */\nlet bufferTreeEvents: boolean = false;\n\n/**\n * Call the provided callback with {@link TreeNode}s' events paused until after the callback's completion.\n *\n * Events that would otherwise have been emitted immediately are merged and buffered until after the\n * provided callback has been completed.\n *\n * @remarks\n * Note: this should be used with caution. User application behaviors are implicitly coupled to event timing.\n * Disrupting this timing can lead to unexpected behavior.\n */\nexport function withBufferedTreeEvents(callback: () => void): void {\n\tif (bufferTreeEvents) {\n\t\t// Already buffering - just run the callback\n\t\tcallback();\n\t} else {\n\t\tbufferTreeEvents = true;\n\t\tconst toFlush: KernelEventBuffer[] = [];\n\t\ttry {\n\t\t\tcallback();\n\t\t} finally {\n\t\t\tbufferTreeEvents = false;\n\t\t\t// Snapshot-and-clear before flushing to safely handle reentrant `withBufferedTreeEvents`\n\t\t\t// calls made by listeners that fire during `buffer.flush()` below:\n\t\t\t// - Iterating an array means a reentrant call's `clear()` cannot truncate our loop\n\t\t\t// and cause buffers later in `activeBuffers` to be skipped (and their events dropped).\n\t\t\t// - Clearing up front means the reentrant call starts from an empty set, so its own\n\t\t\t// finally block only flushes what it buffered - not a re-flush of our remaining buffers.\n\t\t\ttoFlush.push(...activeBuffers);\n\t\t\tactiveBuffers.clear();\n\t\t}\n\n\t\t// Don't flush/emit events in the case of an error\n\t\tfor (const buffer of toFlush) {\n\t\t\tbuffer.flush();\n\t\t}\n\t}\n}\n\n/**\n * Set of {@link KernelEventBuffer}s that have accumulated buffered events during the current\n * {@link withBufferedTreeEvents} window and therefore need to be flushed when it ends.\n *\n * @remarks\n * The set should be empty whenever no buffering window is in progress.\n */\nconst activeBuffers: Set<KernelEventBuffer> = new Set();\n\n/**\n * Test-only accessor for the current size of {@link activeBuffers}.\n * @remarks Only exported for testing purposes. Not intended for any other use.\n */\nexport function TEST_activeBufferCount(): number {\n\treturn activeBuffers.size;\n}\n\n/**\n * Event emitter for {@link TreeNodeKernel}, which optionally buffers events based on {@link bufferTreeEvents}.\n * @remarks When buffering is active, this adds itself to {@link activeBuffers} so that\n * {@link withBufferedTreeEvents} can flush it at the end of the buffering window.\n */\nclass KernelEventBuffer implements Listenable<KernelEvents> {\n\t#disposed: boolean = false;\n\n\treadonly #events = createEmitter<KernelEvents>();\n\n\t#eventSource: Listenable<KernelEvents> & HasListeners<KernelEvents>;\n\treadonly #disposeSourceListeners: Map<keyof KernelEvents, Off> = new Map();\n\n\t/**\n\t * Buffer of fields that have changed since events were paused.\n\t * When events are flushed, a single {@link AnchorEvents.childrenChangedAfterBatch} event will be emitted\n\t * containing the accumulated set of changed fields.\n\t */\n\treadonly #childrenChangedBuffer: Set<FieldKey> = new Set();\n\n\t/**\n\t * Buffer of field marks accumulated since events were paused.\n\t * Emitted alongside the buffered changed-fields set when flushed.\n\t */\n\treadonly #fieldMarksBuffer: Map<FieldKey, readonly DeltaMark[]> = new Map();\n\n\t/**\n\t * Fields whose marks have been permanently invalidated within the current buffer window due to\n\t * two or more separate delta batches touching the same field.\n\t * Once a key is in this set it must never be re-added to the marks buffer, even if\n\t * a third (or later) batch arrives for that field.\n\t */\n\treadonly #invalidatedFieldMarkKeys: Set<FieldKey> = new Set();\n\n\t/**\n\t * Whether or not the subtree has changed since events were paused.\n\t * When events are flushed, a single {@link AnchorEvents.subTreeChanged} event will be emitted if and only\n\t * if the subtree has changed.\n\t */\n\t#subTreeChangedBuffer: boolean = false;\n\n\tpublic constructor(\n\t\t/**\n\t\t * Source of the kernel events.\n\t\t * Subscriptions will be created on-demand when listeners are added to this.events,\n\t\t * and those subscriptions will be cleaned up when all corresponding listeners have been removed.\n\t\t */\n\t\teventSource: Listenable<KernelEvents> & HasListeners<KernelEvents>,\n\t) {\n\t\tthis.#eventSource = eventSource;\n\t}\n\n\t/**\n\t * Migrate this event buffer to a new event source.\n\t *\n\t * @remarks\n\t * Cleans up any existing event subscriptions from the old source.\n\t * Binds events to the new source for each event with active listeners.\n\t */\n\tpublic migrateEventSource(\n\t\tnewSource: Listenable<KernelEvents> & HasListeners<KernelEvents>,\n\t): void {\n\t\t// Unsubscribe from the old source\n\t\tfor (const off of this.#disposeSourceListeners.values()) {\n\t\t\toff();\n\t\t}\n\t\tthis.#disposeSourceListeners.clear();\n\n\t\tthis.#eventSource = newSource;\n\n\t\tif (this.#events.hasListeners(\"childrenChangedAfterBatch\")) {\n\t\t\tconst off = this.#eventSource.on(\n\t\t\t\t\"childrenChangedAfterBatch\",\n\t\t\t\t({ changedFields, fieldMarks }) =>\n\t\t\t\t\tthis.#emit(\"childrenChangedAfterBatch\", { changedFields, fieldMarks }),\n\t\t\t);\n\t\t\tthis.#disposeSourceListeners.set(\"childrenChangedAfterBatch\", off);\n\t\t}\n\t\tif (this.#events.hasListeners(\"subtreeChangedAfterBatch\")) {\n\t\t\tconst off = this.#eventSource.on(\"subtreeChangedAfterBatch\", () =>\n\t\t\t\tthis.#emit(\"subtreeChangedAfterBatch\"),\n\t\t\t);\n\t\t\tthis.#disposeSourceListeners.set(\"subtreeChangedAfterBatch\", off);\n\t\t}\n\t}\n\n\tpublic on(eventName: keyof KernelEvents, listener: KernelEvents[typeof eventName]): Off {\n\t\tthis.#assertNotDisposed();\n\n\t\t// Lazily bind event listeners to the source.\n\t\t// If we do not have any existing listeners for this event, then we need to bind to the source.\n\t\tif (!this.#events.hasListeners(eventName)) {\n\t\t\tassert(\n\t\t\t\t!this.#disposeSourceListeners.has(eventName),\n\t\t\t\t0xc4f /* Should not have a dispose function without listeners */,\n\t\t\t);\n\n\t\t\tconst off: Off =\n\t\t\t\teventName === \"childrenChangedAfterBatch\"\n\t\t\t\t\t? this.#eventSource.on(eventName, (args) => this.#emit(eventName, args))\n\t\t\t\t\t: this.#eventSource.on(eventName, () => this.#emit(eventName));\n\t\t\tthis.#disposeSourceListeners.set(eventName, off);\n\t\t}\n\n\t\tthis.#events.on(eventName, listener);\n\t\t// Return a bound method instead of an arrow closure. A bound function captures\n\t\t// (target, thisArg, ...boundArgs) in a fixed shape that V8 can optimize more\n\t\t// uniformly than a closure that captures its lexical context.\n\t\treturn this.off.bind(this, eventName, listener);\n\t}\n\n\tpublic off(eventName: keyof KernelEvents, listener: KernelEvents[typeof eventName]): void {\n\t\tthis.#events.off(eventName, listener);\n\n\t\t// If there are no remaining listeners for the event, unbind from the source\n\t\tif (!this.#events.hasListeners(eventName)) {\n\t\t\tconst off = this.#disposeSourceListeners.get(eventName);\n\t\t\toff?.();\n\t\t\tthis.#disposeSourceListeners.delete(eventName);\n\t\t}\n\t}\n\n\t#emit(\n\t\teventName: keyof KernelEvents,\n\t\targ?: {\n\t\t\tchangedFields: ReadonlySet<FieldKey>;\n\t\t\tfieldMarks: ReadonlyMap<FieldKey, readonly DeltaMark[]>;\n\t\t},\n\t): void {\n\t\tthis.#assertNotDisposed();\n\t\tswitch (eventName) {\n\t\t\tcase \"childrenChangedAfterBatch\": {\n\t\t\t\tassert(arg !== undefined, 0xcea /* childrenChangedAfterBatch requires arg */);\n\t\t\t\treturn this.#handleChildrenChangedAfterBatch(arg.changedFields, arg.fieldMarks);\n\t\t\t}\n\t\t\tcase \"subtreeChangedAfterBatch\": {\n\t\t\t\treturn this.#handleSubtreeChangedAfterBatch();\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(eventName);\n\t\t\t}\n\t\t}\n\t}\n\n\t#handleChildrenChangedAfterBatch(\n\t\tchangedFields: ReadonlySet<FieldKey>,\n\t\tfieldMarks: ReadonlyMap<FieldKey, readonly DeltaMark[]>,\n\t): void {\n\t\tif (bufferTreeEvents) {\n\t\t\tactiveBuffers.add(this);\n\t\t\tfor (const fieldKey of changedFields) {\n\t\t\t\tthis.#childrenChangedBuffer.add(fieldKey);\n\t\t\t}\n\t\t\tfor (const [key, marks] of fieldMarks) {\n\t\t\t\tif (this.#invalidatedFieldMarkKeys.has(key)) {\n\t\t\t\t\t// Already permanently invalidated by an earlier collision; ignore this batch too.\n\t\t\t\t\t// TODO: Once the eventing stack is rewritten to walk the composed delta at flush\n\t\t\t\t\t// time, this collision path will be unreachable and can be removed entirely.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (this.#fieldMarksBuffer.has(key)) {\n\t\t\t\t\t// A second batch of marks arrived for the same field before the buffer was flushed.\n\t\t\t\t\t// We have no delta composition logic, so permanently invalidate this field so that\n\t\t\t\t\t// any further batches are also discarded rather than incorrectly surfaced.\n\t\t\t\t\tthis.#fieldMarksBuffer.delete(key);\n\t\t\t\t\tthis.#invalidatedFieldMarkKeys.add(key);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#fieldMarksBuffer.set(key, marks);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#events.emit(\"childrenChangedAfterBatch\", { changedFields, fieldMarks });\n\t\t}\n\t}\n\n\t#handleSubtreeChangedAfterBatch(): void {\n\t\tif (bufferTreeEvents) {\n\t\t\tactiveBuffers.add(this);\n\t\t\tthis.#subTreeChangedBuffer = true;\n\t\t} else {\n\t\t\tthis.#events.emit(\"subtreeChangedAfterBatch\");\n\t\t}\n\t}\n\n\t/**\n\t * Flushes any events buffered due to {@link withBufferedTreeEvents}.\n\t */\n\tpublic flush(): void {\n\t\tthis.#assertNotDisposed();\n\n\t\tif (this.#childrenChangedBuffer.size > 0) {\n\t\t\tthis.#events.emit(\"childrenChangedAfterBatch\", {\n\t\t\t\tchangedFields: this.#childrenChangedBuffer,\n\t\t\t\tfieldMarks: this.#fieldMarksBuffer,\n\t\t\t});\n\t\t\tthis.#childrenChangedBuffer.clear();\n\t\t\tthis.#fieldMarksBuffer.clear();\n\t\t\tthis.#invalidatedFieldMarkKeys.clear();\n\t\t}\n\n\t\tif (this.#subTreeChangedBuffer) {\n\t\t\tthis.#events.emit(\"subtreeChangedAfterBatch\");\n\t\t\tthis.#subTreeChangedBuffer = false;\n\t\t}\n\t}\n\n\t#assertNotDisposed(): void {\n\t\tassert(!this.#disposed, 0xc51 /* Event handler disposed. */);\n\t}\n\n\tpublic dispose(): void {\n\t\tif (this.#disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebugAssert(\n\t\t\t() =>\n\t\t\t\t(this.#childrenChangedBuffer.size === 0 && !this.#subTreeChangedBuffer) ||\n\t\t\t\t\"Buffered kernel events should have been flushed before disposing.\",\n\t\t);\n\t\tdebugAssert(\n\t\t\t() => !activeBuffers.has(this) || \"Disposed buffer should not be in activeBuffers.\",\n\t\t);\n\n\t\tfor (const off of this.#disposeSourceListeners.values()) {\n\t\t\toff();\n\t\t}\n\t\tthis.#disposeSourceListeners.clear();\n\n\t\tthis.#childrenChangedBuffer.clear();\n\t\tthis.#fieldMarksBuffer.clear();\n\t\tthis.#invalidatedFieldMarkKeys.clear();\n\t\tthis.#subTreeChangedBuffer = false;\n\n\t\tthis.#disposed = true;\n\t}\n}\n\n// #endregion\n\n/**\n * For hydrated nodes this is a HydratedFlexTreeNode thats a projection of forest content.\n * For {@link Unhydrated} nodes this is a UnhydratedFlexTreeNode.\n */\nexport type InnerNode = FlexTreeNode;\n\n/**\n * Narrows innerNode to either {@link UnhydratedFlexTreeNode} or {@link HydratedFlexTreeNode}.\n */\nexport function splitInnerNodeType(\n\tinnerNode: InnerNode,\n): asserts innerNode is UnhydratedFlexTreeNode | HydratedFlexTreeNode {\n\tassert(\n\t\tinnerNode instanceof UnhydratedFlexTreeNode || innerNode.isHydrated(),\n\t\t0xbc8 /* Invalid inner node type */,\n\t);\n}\n\n/**\n * An anchor slot which associates an anchor with its corresponding {@link TreeNode}, if there is one.\n * @remarks\n * For this to work, we have to require that there is at most a single view using a given AnchorSet.\n * FlexTree already has this assumption, and we also assume there is a single simple-tree per FlexTree, so this is valid.\n */\nexport const simpleTreeNodeSlot = anchorSlot<TreeNode>();\n\n/**\n * Dispose a TreeNode (if any) for an existing anchor without disposing the anchor.\n */\nexport function tryDisposeTreeNode(anchorNode: AnchorNode): void {\n\tconst treeNode = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (treeNode !== undefined) {\n\t\tconst kernel = getKernel(treeNode);\n\t\tkernel.dispose();\n\t\tanchorNode.slots.delete(simpleTreeNodeSlot);\n\t}\n}\n\n/**\n * Gets the {@link TreeNodeSchema} for the {@link InnerNode}.\n */\nexport function getSimpleNodeSchemaFromInnerNode(innerNode: InnerNode): TreeNodeSchema {\n\tconst context: Context = getSimpleContextFromInnerNode(innerNode);\n\treturn context.schema.get(innerNode.type) ?? fail(0xb3f /* missing schema from context */);\n}\n\n/**\n * Gets the {@link Context} for the {@link InnerNode}.\n */\nexport function getSimpleContextFromInnerNode(innerNode: InnerNode): Context {\n\tsplitInnerNodeType(innerNode);\n\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\treturn innerNode.simpleContext;\n\t}\n\n\tconst context = innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot);\n\tassert(context !== undefined, 0xa55 /* missing simple tree context */);\n\n\treturn context;\n}\n\n/**\n * Retrieves the flex node associated with the given target.\n * @remarks\n * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n *\n * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n *\n * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n */\nexport function getInnerNode(treeNode: TreeNode): InnerNode {\n\tconst kernel = getKernel(treeNode);\n\treturn kernel.getInnerNode();\n}\n\n/**\n * Gets a flex node from an anchor node\n */\nfunction flexNodeFromAnchor(anchorNode: AnchorNode): HydratedFlexTreeNode {\n\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\tif (flexNode !== undefined) {\n\t\treturn flexNode; // If it does have a flex node, return it...\n\t} // ...otherwise, the flex node must be created\n\tconst context =\n\t\tanchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb45 /* missing context */);\n\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\tconst newFlexNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\tcursor.free();\n\treturn newFlexNode;\n}\n\n/**\n * Gets a tree node from an anchor node\n */\nexport function treeNodeFromAnchor(anchorNode: AnchorNode): TreeNode | TreeValue {\n\tconst cached = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst flexNode = flexNodeFromAnchor(anchorNode);\n\treturn createTreeNodeFromInner(flexNode);\n}\n\n/**\n * Constructs a TreeNode from an InnerNode.\n * @remarks\n * This does not do caching or validation: caller must ensure duplicate nodes for a given inner node are not created, and that the inner node is valid.\n */\nexport function createTreeNodeFromInner(innerNode: InnerNode): TreeNode | TreeValue {\n\tconst classSchema = getSimpleNodeSchemaFromInnerNode(innerNode);\n\tconst internal = innerNode as unknown as InternalTreeNode;\n\treturn typeof classSchema === \"function\"\n\t\t? new classSchema(internal)\n\t\t: (classSchema as { create(data: InternalTreeNode): TreeNode | TreeValue }).create(\n\t\t\t\tinternal,\n\t\t\t);\n}\n\n/**\n * Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.\n * This slot is used to detect if one already exists and error if creating a second.\n * @remarks\n * See also {@link ContextSlot} in which the flex-tree context is stored.\n */\nexport const SimpleContextSlot = anchorSlot<HydratedContext>();\n"]}
1
+ {"version":3,"file":"treeNodeKernel.js","sourceRoot":"","sources":["../../../src/simple-tree/core/treeNodeKernel.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 { createEmitter } from \"@fluid-internal/client-utils\";\nimport type { HasListeners, Listenable, Off } from \"@fluidframework/core-interfaces/internal\";\nimport {\n\tassert,\n\tfail,\n\tdebugAssert,\n\tunreachableCase,\n} from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tanchorSlot,\n\ttype AnchorEvents,\n\ttype AnchorNode,\n\ttype DeltaMark,\n\ttype FieldKey,\n\ttype TreeValue,\n} from \"../../core/index.js\";\nimport { getOrCreateHydratedFlexTreeNode } from \"../../feature-libraries/index.js\";\nimport {\n\tContextSlot,\n\tflexTreeSlot,\n\tLazyEntity,\n\tTreeStatus,\n\ttreeStatusFromAnchorCache,\n\ttype FlexTreeNode,\n\ttype HydratedFlexTreeNode,\n} from \"../../feature-libraries/index.js\";\n\nimport type { Context, HydratedContext } from \"./context.js\";\nimport type { TreeNode } from \"./treeNode.js\";\nimport type { TreeNodeSchema } from \"./treeNodeSchema.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport { UnhydratedFlexTreeNode } from \"./unhydratedFlexTree.js\";\n\nconst treeNodeToKernel = new WeakMap<TreeNode, TreeNodeKernel>();\n\nexport function getKernel(node: TreeNode): TreeNodeKernel {\n\tconst kernel = treeNodeToKernel.get(node);\n\tassert(kernel !== undefined, 0x9b1 /* Expected tree node to have kernel */);\n\treturn kernel;\n}\n\n/**\n * Detects if the given 'candidate' is a TreeNode.\n *\n * @remarks\n * Supports both Hydrated and {@link Unhydrated} TreeNodes, both of which return true.\n *\n * Because the common usage is to check if a value being inserted/set is a TreeNode,\n * this function permits calling with primitives as well as objects.\n *\n * Primitives will always return false (as they are copies of data, not references to nodes).\n *\n * @param candidate - Value which may be a TreeNode\n * @returns true if the given 'candidate' is a hydrated TreeNode.\n */\nexport function isTreeNode(candidate: unknown): candidate is TreeNode | Unhydrated<TreeNode> {\n\treturn treeNodeToKernel.has(candidate as TreeNode);\n}\n\n/**\n * Returns a schema for a value if the value is a {@link TreeNode}.\n *\n * Returns undefined for other values.\n * @remarks\n * Does not give schema for a {@link TreeLeafValue}.\n */\nexport function tryGetTreeNodeSchema(value: unknown): undefined | TreeNodeSchema {\n\tconst kernel = treeNodeToKernel.get(value as TreeNode);\n\treturn kernel?.schema;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} before the kernel is hydrated */\ninterface UnhydratedState {\n\treadonly innerNode: UnhydratedFlexTreeNode;\n}\n\n/** The {@link HydrationState} of a {@link TreeNodeKernel} after the kernel is hydrated */\ninterface HydratedState {\n\t/** The flex node for this kernel */\n\treadonly innerNode: HydratedFlexTreeNode;\n\t/** All {@link Off | event deregistration functions} that should be run when the kernel is disposed. */\n\treadonly offAnchorNode: Set<Off>;\n}\n\n/** State within a {@link TreeNodeKernel} that is related to the hydration process */\ntype HydrationState = UnhydratedState | HydratedState;\n\n/** True if and only if the given {@link HydrationState} is post-hydration */\nfunction isHydrated(state: HydrationState): state is HydratedState {\n\treturn state.innerNode.isHydrated();\n}\n\n/**\n * Contains state and an internal API for managing {@link TreeNode}s.\n * @remarks All {@link TreeNode}s have an associated kernel object.\n * The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.\n */\nexport class TreeNodeKernel {\n\tprivate disposed = false;\n\n\t/**\n\t * Generation number which is incremented any time we have an edit on the node.\n\t * Used during iteration to make sure there has been no edits that were concurrently made.\n\t * @remarks\n\t * This is updated monotonically by this class when edits are applied.\n\t * TODO: update this when applying edits to unhydrated trees.\n\t *\n\t * If TypeScript supported making this immutable from outside the class without making it readonly from inside, that would be used here,\n\t * but they only way to do that is add a separate public accessor and make it private, which was deemed not worth the boilerplate, runtime overhead and bundle size.\n\t */\n\tpublic generationNumber: number = 0;\n\n\t#hydrationState: HydrationState;\n\n\t/**\n\t * Handler for events listeners registered with the kernel.\n\t *\n\t * @remarks\n\t * Supports event buffering via {@link withBufferedEvents}.\n\t *\n\t * Allocated lazily on first access to {@link TreeNodeKernel.events}.\n\t * We expect the majority of nodes to never have event listeners registered, so\n\t * deferring construction avoids per-kernel allocations.\n\t */\n\t#eventBuffer: KernelEventBuffer | undefined;\n\n\t/**\n\t * Create a TreeNodeKernel which can be looked up with {@link getKernel}.\n\t *\n\t * @param initialContext - context from when this node was originally created. Only used when unhydrated.\n\t * @param innerNode - When unhydrated the MapTreeNode. Otherwise HydratedFlexTreeNode.\n\t * @remarks\n\t * Exactly one kernel per TreeNode should be created.\n\t */\n\tpublic constructor(\n\t\tpublic readonly node: TreeNode,\n\t\tpublic readonly schema: TreeNodeSchema,\n\t\tinnerNode: InnerNode,\n\t\tprivate readonly initialContext: Context,\n\t) {\n\t\tsplitInnerNodeType(innerNode);\n\n\t\tassert(!treeNodeToKernel.has(node), 0xa1a /* only one kernel per node can be made */);\n\t\ttreeNodeToKernel.set(node, this);\n\n\t\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\t\t// Unhydrated case\n\n\t\t\tdebugAssert(() => innerNode.treeNode === undefined);\n\t\t\tinnerNode.treeNode = node;\n\n\t\t\tthis.#hydrationState = {\n\t\t\t\tinnerNode,\n\t\t\t};\n\t\t} else {\n\t\t\t// Hydrated case\n\t\t\tthis.#hydrationState = this.createHydratedState(innerNode);\n\t\t}\n\t}\n\n\tpublic get context(): Context {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\t// This can't be cached on this.#hydrated during hydration since initial tree is hydrated before the context is cached on the anchorSet.\n\t\t\treturn (\n\t\t\t\tthis.#hydrationState.innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot) ??\n\t\t\t\tfail(0xb40 /* missing simple-tree context */)\n\t\t\t);\n\t\t}\n\t\treturn this.initialContext;\n\t}\n\n\t/**\n\t * Transition from {@link Unhydrated} to hydrated.\n\t * Bi-directionally associates the given hydrated TreeNode to the HydratedFlexTreeNode.\n\t * @remarks\n\t * Happens at most once for any given node.\n\t * Cleans up mappings to {@link UnhydratedFlexTreeNode} - it is assumed that they are no longer needed once this node has an anchor node.\n\t */\n\tpublic hydrate(inner: HydratedFlexTreeNode): void {\n\t\tassert(!this.disposed, 0xa2a /* cannot hydrate a disposed node */);\n\t\tassert(!isHydrated(this.#hydrationState), 0xa2b /* hydration should only happen once */);\n\n\t\tthis.#hydrationState = this.createHydratedState(inner);\n\n\t\t// Lazily migrate existing event listeners to the anchor node.\n\t\t// If no one ever subscribed to this kernel's events, the buffer was never allocated\n\t\t// and there is nothing to migrate.\n\t\tthis.#eventBuffer?.migrateEventSource(inner.anchorNode.events);\n\t}\n\n\tprivate createHydratedState(innerNode: HydratedFlexTreeNode): HydratedState {\n\t\tassert(\n\t\t\t!innerNode.anchorNode.slots.has(simpleTreeNodeSlot),\n\t\t\t0x7f5 /* Cannot associate an flex node with multiple simple-tree nodes */,\n\t\t);\n\t\tinnerNode.anchorNode.slots.set(simpleTreeNodeSlot, this.node);\n\t\treturn {\n\t\t\tinnerNode,\n\t\t\toffAnchorNode: new Set([\n\t\t\t\tinnerNode.anchorNode.events.on(\"afterDestroy\", () => this.dispose()),\n\t\t\t\t// TODO: this should be triggered on change even for unhydrated nodes.\n\t\t\t\tinnerNode.anchorNode.events.on(\"childrenChanging\", () => {\n\t\t\t\t\tthis.generationNumber += 1;\n\t\t\t\t}),\n\t\t\t]),\n\t\t};\n\t}\n\n\tpublic getStatus(): TreeStatus {\n\t\tif (this.disposed) {\n\t\t\treturn TreeStatus.Deleted;\n\t\t}\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\treturn TreeStatus.New;\n\t\t}\n\n\t\t// TODO: Replace this check with the proper check against the cursor state when the cursor becomes part of the kernel\n\t\tconst flex = this.#hydrationState.innerNode.anchorNode.slots.get(flexTreeSlot);\n\t\tif (flex !== undefined) {\n\t\t\tassert(flex instanceof LazyEntity, 0x9b4 /* Unexpected flex node implementation */);\n\t\t\tif (flex.isFreed()) {\n\t\t\t\treturn TreeStatus.Deleted;\n\t\t\t}\n\t\t}\n\n\t\treturn treeStatusFromAnchorCache(this.#hydrationState.innerNode.anchorNode);\n\t}\n\n\tpublic get events(): Listenable<KernelEvents> {\n\t\tassert(!this.disposed, 0xcfa /* Cannot register events on a disposed node */);\n\t\t// Allocate the buffer on first access. See {@link TreeNodeKernel.#eventBuffer} for rationale.\n\t\tif (this.#eventBuffer === undefined) {\n\t\t\tconst eventSource = isHydrated(this.#hydrationState)\n\t\t\t\t? this.#hydrationState.innerNode.anchorNode.events\n\t\t\t\t: this.#hydrationState.innerNode.events;\n\t\t\tthis.#eventBuffer = new KernelEventBuffer(eventSource);\n\t\t}\n\t\treturn this.#eventBuffer;\n\t}\n\n\tpublic dispose(): void {\n\t\tdebugAssert(() => !this.disposed || \"Cannot dispose a disposed node\");\n\t\tthis.disposed = true;\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\tfor (const off of this.#hydrationState.offAnchorNode) {\n\t\t\t\toff();\n\t\t\t}\n\t\t}\n\t\tthis.#eventBuffer?.dispose();\n\t\t// TODO: go to the context and remove myself from withAnchors\n\t}\n\n\tpublic isHydrated(): this is { anchorNode: AnchorNode; context: HydratedContext } {\n\t\treturn isHydrated(this.#hydrationState);\n\t}\n\n\tpublic get anchorNode(): AnchorNode | undefined {\n\t\treturn isHydrated(this.#hydrationState)\n\t\t\t? this.#hydrationState.innerNode.anchorNode\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Retrieves the flex node associated with the given target.\n\t * @remarks\n\t * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n\t *\n\t * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n\t *\n\t * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n\t */\n\tpublic getInnerNode(): InnerNode {\n\t\tif (!isHydrated(this.#hydrationState)) {\n\t\t\tdebugAssert(\n\t\t\t\t() =>\n\t\t\t\t\tthis.#hydrationState.innerNode?.context.isDisposed() === false ||\n\t\t\t\t\t\"Unhydrated node should never be disposed\",\n\t\t\t);\n\t\t\treturn this.#hydrationState.innerNode; // Unhydrated case\n\t\t}\n\n\t\tif (this.disposed) {\n\t\t\tthrow new UsageError(\"Cannot access a deleted node.\");\n\t\t}\n\n\t\treturn this.#hydrationState.innerNode;\n\t}\n\n\t/**\n\t * Retrieves the {@link UnhydratedFlexTreeNode} if unhydrated. otherwise undefined.\n\t */\n\tpublic getInnerNodeIfUnhydrated(): UnhydratedFlexTreeNode | undefined {\n\t\tif (isHydrated(this.#hydrationState)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.#hydrationState.innerNode;\n\t}\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst kernelEvents = [\"childrenChangedAfterBatch\", \"subtreeChangedAfterBatch\"] as const;\n\ntype KernelEvents = Pick<AnchorEvents, (typeof kernelEvents)[number]>;\n\n// #region TreeNodeEventBuffer\n\n/**\n * Whether or not events from {@link TreeNodeKernel} should be buffered instead of emitted immediately.\n */\nlet bufferTreeEvents: boolean = false;\n\n/**\n * Call the provided callback with {@link TreeNode}s' events paused until after the callback's completion.\n *\n * Events that would otherwise have been emitted immediately are merged and buffered until after the\n * provided callback has been completed.\n *\n * @remarks\n * Note: this should be used with caution. User application behaviors are implicitly coupled to event timing.\n * Disrupting this timing can lead to unexpected behavior.\n */\nexport function withBufferedTreeEvents(callback: () => void): void {\n\tif (bufferTreeEvents) {\n\t\t// Already buffering - just run the callback\n\t\tcallback();\n\t} else {\n\t\tbufferTreeEvents = true;\n\t\tconst toFlush: KernelEventBuffer[] = [];\n\t\ttry {\n\t\t\tcallback();\n\t\t} finally {\n\t\t\tbufferTreeEvents = false;\n\t\t\t// Snapshot-and-clear before flushing to safely handle reentrant `withBufferedTreeEvents`\n\t\t\t// calls made by listeners that fire during `buffer.flush()` below:\n\t\t\t// - Iterating an array means a reentrant call's `clear()` cannot truncate our loop\n\t\t\t// and cause buffers later in `activeBuffers` to be skipped (and their events dropped).\n\t\t\t// - Clearing up front means the reentrant call starts from an empty set, so its own\n\t\t\t// finally block only flushes what it buffered - not a re-flush of our remaining buffers.\n\t\t\ttoFlush.push(...activeBuffers);\n\t\t\tactiveBuffers.clear();\n\t\t}\n\n\t\t// Don't flush/emit events in the case of an error\n\t\tfor (const buffer of toFlush) {\n\t\t\tbuffer.flush();\n\t\t}\n\t}\n}\n\n/**\n * Set of {@link KernelEventBuffer}s that have accumulated buffered events during the current\n * {@link withBufferedTreeEvents} window and therefore need to be flushed when it ends.\n *\n * @remarks\n * The set should be empty whenever no buffering window is in progress.\n */\nconst activeBuffers: Set<KernelEventBuffer> = new Set();\n\n/**\n * Test-only accessor for the current size of {@link activeBuffers}.\n * @remarks Only exported for testing purposes. Not intended for any other use.\n */\nexport function TEST_activeBufferCount(): number {\n\treturn activeBuffers.size;\n}\n\n/**\n * Event emitter for {@link TreeNodeKernel}, which optionally buffers events based on {@link bufferTreeEvents}.\n * @remarks When buffering is active, this adds itself to {@link activeBuffers} so that\n * {@link withBufferedTreeEvents} can flush it at the end of the buffering window.\n */\nclass KernelEventBuffer implements Listenable<KernelEvents> {\n\t#disposed: boolean = false;\n\n\treadonly #events = createEmitter<KernelEvents>();\n\n\t#eventSource: Listenable<KernelEvents> & HasListeners<KernelEvents>;\n\treadonly #disposeSourceListeners: Map<keyof KernelEvents, Off> = new Map();\n\n\t/**\n\t * Buffer of fields that have changed since events were paused.\n\t * When events are flushed, a single {@link AnchorEvents.childrenChangedAfterBatch} event will be emitted\n\t * containing the accumulated set of changed fields.\n\t */\n\treadonly #childrenChangedBuffer: Set<FieldKey> = new Set();\n\n\t/**\n\t * Buffer of field marks accumulated since events were paused.\n\t * Emitted alongside the buffered changed-fields set when flushed.\n\t */\n\treadonly #fieldMarksBuffer: Map<FieldKey, readonly DeltaMark[]> = new Map();\n\n\t/**\n\t * Fields whose marks have been permanently invalidated within the current buffer window due to\n\t * two or more separate delta batches touching the same field.\n\t * Once a key is in this set it must never be re-added to the marks buffer, even if\n\t * a third (or later) batch arrives for that field.\n\t */\n\treadonly #invalidatedFieldMarkKeys: Set<FieldKey> = new Set();\n\n\t/**\n\t * Whether or not the subtree has changed since events were paused.\n\t * When events are flushed, a single {@link AnchorEvents.subTreeChanged} event will be emitted if and only\n\t * if the subtree has changed.\n\t */\n\t#subTreeChangedBuffer: boolean = false;\n\n\tpublic constructor(\n\t\t/**\n\t\t * Source of the kernel events.\n\t\t * Subscriptions will be created on-demand when listeners are added to this.events,\n\t\t * and those subscriptions will be cleaned up when all corresponding listeners have been removed.\n\t\t */\n\t\teventSource: Listenable<KernelEvents> & HasListeners<KernelEvents>,\n\t) {\n\t\tthis.#eventSource = eventSource;\n\t}\n\n\t/**\n\t * Migrate this event buffer to a new event source.\n\t *\n\t * @remarks\n\t * Cleans up any existing event subscriptions from the old source.\n\t * Binds events to the new source for each event with active listeners.\n\t */\n\tpublic migrateEventSource(\n\t\tnewSource: Listenable<KernelEvents> & HasListeners<KernelEvents>,\n\t): void {\n\t\t// Unsubscribe from the old source\n\t\tfor (const off of this.#disposeSourceListeners.values()) {\n\t\t\toff();\n\t\t}\n\t\tthis.#disposeSourceListeners.clear();\n\n\t\tthis.#eventSource = newSource;\n\n\t\tif (this.#events.hasListeners(\"childrenChangedAfterBatch\")) {\n\t\t\tconst off = this.#eventSource.on(\n\t\t\t\t\"childrenChangedAfterBatch\",\n\t\t\t\t({ changedFields, fieldMarks }) =>\n\t\t\t\t\tthis.#emit(\"childrenChangedAfterBatch\", { changedFields, fieldMarks }),\n\t\t\t);\n\t\t\tthis.#disposeSourceListeners.set(\"childrenChangedAfterBatch\", off);\n\t\t}\n\t\tif (this.#events.hasListeners(\"subtreeChangedAfterBatch\")) {\n\t\t\tconst off = this.#eventSource.on(\"subtreeChangedAfterBatch\", () =>\n\t\t\t\tthis.#emit(\"subtreeChangedAfterBatch\"),\n\t\t\t);\n\t\t\tthis.#disposeSourceListeners.set(\"subtreeChangedAfterBatch\", off);\n\t\t}\n\t}\n\n\tpublic on(eventName: keyof KernelEvents, listener: KernelEvents[typeof eventName]): Off {\n\t\tthis.#assertNotDisposed();\n\n\t\t// Lazily bind event listeners to the source.\n\t\t// If we do not have any existing listeners for this event, then we need to bind to the source.\n\t\tif (!this.#events.hasListeners(eventName)) {\n\t\t\tassert(\n\t\t\t\t!this.#disposeSourceListeners.has(eventName),\n\t\t\t\t0xc4f /* Should not have a dispose function without listeners */,\n\t\t\t);\n\n\t\t\tconst off: Off =\n\t\t\t\teventName === \"childrenChangedAfterBatch\"\n\t\t\t\t\t? this.#eventSource.on(eventName, (args) => this.#emit(eventName, args))\n\t\t\t\t\t: this.#eventSource.on(eventName, () => this.#emit(eventName));\n\t\t\tthis.#disposeSourceListeners.set(eventName, off);\n\t\t}\n\n\t\tthis.#events.on(eventName, listener);\n\t\t// Return a bound method instead of an arrow closure. A bound function captures\n\t\t// (target, thisArg, ...boundArgs) in a fixed shape that V8 can optimize more\n\t\t// uniformly than a closure that captures its lexical context.\n\t\treturn this.off.bind(this, eventName, listener);\n\t}\n\n\tpublic off(eventName: keyof KernelEvents, listener: KernelEvents[typeof eventName]): void {\n\t\tthis.#events.off(eventName, listener);\n\n\t\t// If there are no remaining listeners for the event, unbind from the source\n\t\tif (!this.#events.hasListeners(eventName)) {\n\t\t\tconst off = this.#disposeSourceListeners.get(eventName);\n\t\t\toff?.();\n\t\t\tthis.#disposeSourceListeners.delete(eventName);\n\t\t}\n\t}\n\n\t#emit(\n\t\teventName: keyof KernelEvents,\n\t\targ?: {\n\t\t\tchangedFields: ReadonlySet<FieldKey>;\n\t\t\tfieldMarks: ReadonlyMap<FieldKey, readonly DeltaMark[]>;\n\t\t},\n\t): void {\n\t\tthis.#assertNotDisposed();\n\t\tswitch (eventName) {\n\t\t\tcase \"childrenChangedAfterBatch\": {\n\t\t\t\tassert(arg !== undefined, 0xcea /* childrenChangedAfterBatch requires arg */);\n\t\t\t\treturn this.#handleChildrenChangedAfterBatch(arg.changedFields, arg.fieldMarks);\n\t\t\t}\n\t\t\tcase \"subtreeChangedAfterBatch\": {\n\t\t\t\treturn this.#handleSubtreeChangedAfterBatch();\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(eventName);\n\t\t\t}\n\t\t}\n\t}\n\n\t#handleChildrenChangedAfterBatch(\n\t\tchangedFields: ReadonlySet<FieldKey>,\n\t\tfieldMarks: ReadonlyMap<FieldKey, readonly DeltaMark[]>,\n\t): void {\n\t\tif (bufferTreeEvents) {\n\t\t\tactiveBuffers.add(this);\n\t\t\tfor (const fieldKey of changedFields) {\n\t\t\t\tthis.#childrenChangedBuffer.add(fieldKey);\n\t\t\t}\n\t\t\tfor (const [key, marks] of fieldMarks) {\n\t\t\t\tif (this.#invalidatedFieldMarkKeys.has(key)) {\n\t\t\t\t\t// Already permanently invalidated by an earlier collision; ignore this batch too.\n\t\t\t\t\t// TODO: Once the eventing stack is rewritten to walk the composed delta at flush\n\t\t\t\t\t// time, this collision path will be unreachable and can be removed entirely.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (this.#fieldMarksBuffer.has(key)) {\n\t\t\t\t\t// A second batch of marks arrived for the same field before the buffer was flushed.\n\t\t\t\t\t// We have no delta composition logic, so permanently invalidate this field so that\n\t\t\t\t\t// any further batches are also discarded rather than incorrectly surfaced.\n\t\t\t\t\tthis.#fieldMarksBuffer.delete(key);\n\t\t\t\t\tthis.#invalidatedFieldMarkKeys.add(key);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#fieldMarksBuffer.set(key, marks);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#events.emit(\"childrenChangedAfterBatch\", { changedFields, fieldMarks });\n\t\t}\n\t}\n\n\t#handleSubtreeChangedAfterBatch(): void {\n\t\tif (bufferTreeEvents) {\n\t\t\tactiveBuffers.add(this);\n\t\t\tthis.#subTreeChangedBuffer = true;\n\t\t} else {\n\t\t\tthis.#events.emit(\"subtreeChangedAfterBatch\");\n\t\t}\n\t}\n\n\t/**\n\t * Flushes any events buffered due to {@link withBufferedTreeEvents}.\n\t */\n\tpublic flush(): void {\n\t\tthis.#assertNotDisposed();\n\n\t\tif (this.#childrenChangedBuffer.size > 0) {\n\t\t\tthis.#events.emit(\"childrenChangedAfterBatch\", {\n\t\t\t\tchangedFields: this.#childrenChangedBuffer,\n\t\t\t\tfieldMarks: this.#fieldMarksBuffer,\n\t\t\t});\n\t\t\tthis.#childrenChangedBuffer.clear();\n\t\t\tthis.#fieldMarksBuffer.clear();\n\t\t\tthis.#invalidatedFieldMarkKeys.clear();\n\t\t}\n\n\t\tif (this.#subTreeChangedBuffer) {\n\t\t\tthis.#events.emit(\"subtreeChangedAfterBatch\");\n\t\t\tthis.#subTreeChangedBuffer = false;\n\t\t}\n\t}\n\n\t#assertNotDisposed(): void {\n\t\tassert(!this.#disposed, 0xc51 /* Event handler disposed. */);\n\t}\n\n\tpublic dispose(): void {\n\t\tif (this.#disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebugAssert(\n\t\t\t() =>\n\t\t\t\t(this.#childrenChangedBuffer.size === 0 && !this.#subTreeChangedBuffer) ||\n\t\t\t\t\"Buffered kernel events should have been flushed before disposing.\",\n\t\t);\n\t\tdebugAssert(\n\t\t\t() => !activeBuffers.has(this) || \"Disposed buffer should not be in activeBuffers.\",\n\t\t);\n\n\t\tfor (const off of this.#disposeSourceListeners.values()) {\n\t\t\toff();\n\t\t}\n\t\tthis.#disposeSourceListeners.clear();\n\n\t\tthis.#childrenChangedBuffer.clear();\n\t\tthis.#fieldMarksBuffer.clear();\n\t\tthis.#invalidatedFieldMarkKeys.clear();\n\t\tthis.#subTreeChangedBuffer = false;\n\n\t\tthis.#disposed = true;\n\t}\n}\n\n// #endregion\n\n/**\n * For hydrated nodes this is a HydratedFlexTreeNode thats a projection of forest content.\n * For {@link Unhydrated} nodes this is a UnhydratedFlexTreeNode.\n */\nexport type InnerNode = FlexTreeNode;\n\n/**\n * Narrows innerNode to either {@link UnhydratedFlexTreeNode} or {@link HydratedFlexTreeNode}.\n */\nexport function splitInnerNodeType(\n\tinnerNode: InnerNode,\n): asserts innerNode is UnhydratedFlexTreeNode | HydratedFlexTreeNode {\n\tassert(\n\t\tinnerNode instanceof UnhydratedFlexTreeNode || innerNode.isHydrated(),\n\t\t0xbc8 /* Invalid inner node type */,\n\t);\n}\n\n/**\n * An anchor slot which associates an anchor with its corresponding {@link TreeNode}, if there is one.\n * @remarks\n * For this to work, we have to require that there is at most a single view using a given AnchorSet.\n * FlexTree already has this assumption, and we also assume there is a single simple-tree per FlexTree, so this is valid.\n */\nexport const simpleTreeNodeSlot = anchorSlot<TreeNode>();\n\n/**\n * Dispose a TreeNode (if any) for an existing anchor without disposing the anchor.\n */\nexport function tryDisposeTreeNode(anchorNode: AnchorNode): void {\n\tconst treeNode = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (treeNode !== undefined) {\n\t\tconst kernel = getKernel(treeNode);\n\t\tkernel.dispose();\n\t\tanchorNode.slots.delete(simpleTreeNodeSlot);\n\t}\n}\n\n/**\n * Gets the {@link TreeNodeSchema} for the {@link InnerNode}.\n */\nexport function getSimpleNodeSchemaFromInnerNode(innerNode: InnerNode): TreeNodeSchema {\n\tconst context: Context = getSimpleContextFromInnerNode(innerNode);\n\treturn context.schema.get(innerNode.type) ?? fail(0xb3f /* missing schema from context */);\n}\n\n/**\n * Gets the {@link Context} for the {@link InnerNode}.\n */\nexport function getSimpleContextFromInnerNode(innerNode: InnerNode): Context {\n\tsplitInnerNodeType(innerNode);\n\tif (innerNode instanceof UnhydratedFlexTreeNode) {\n\t\treturn innerNode.simpleContext;\n\t}\n\n\tconst context = innerNode.anchorNode.anchorSet.slots.get(SimpleContextSlot);\n\tassert(context !== undefined, 0xa55 /* missing simple tree context */);\n\n\treturn context;\n}\n\n/**\n * Retrieves the flex node associated with the given target.\n * @remarks\n * For {@link Unhydrated} nodes, this returns the MapTreeNode.\n *\n * For hydrated nodes it returns a FlexTreeNode backed by the forest.\n *\n * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.\n */\nexport function getInnerNode(treeNode: TreeNode): InnerNode {\n\tconst kernel = getKernel(treeNode);\n\treturn kernel.getInnerNode();\n}\n\n/**\n * Gets a flex node from an anchor node\n */\nfunction flexNodeFromAnchor(anchorNode: AnchorNode): HydratedFlexTreeNode {\n\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\tif (flexNode !== undefined) {\n\t\treturn flexNode; // If it does have a flex node, return it...\n\t} // ...otherwise, the flex node must be created\n\tconst context =\n\t\tanchorNode.anchorSet.slots.get(ContextSlot) ?? fail(0xb45 /* missing context */);\n\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\tconst newFlexNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\tcursor.free();\n\treturn newFlexNode;\n}\n\n/**\n * Gets a tree node from an anchor node\n */\nexport function treeNodeFromAnchor(anchorNode: AnchorNode): TreeNode | TreeValue {\n\tconst cached = anchorNode.slots.get(simpleTreeNodeSlot);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst flexNode = flexNodeFromAnchor(anchorNode);\n\treturn createTreeNodeFromInner(flexNode);\n}\n\n/**\n * Constructs a TreeNode from an InnerNode.\n * @remarks\n * This does not do caching or validation: caller must ensure duplicate nodes for a given inner node are not created, and that the inner node is valid.\n */\nexport function createTreeNodeFromInner(innerNode: InnerNode): TreeNode | TreeValue {\n\tconst classSchema = getSimpleNodeSchemaFromInnerNode(innerNode);\n\tconst internal = innerNode as unknown as InternalTreeNode;\n\treturn typeof classSchema === \"function\"\n\t\t? new classSchema(internal)\n\t\t: (classSchema as { create(data: InternalTreeNode): TreeNode | TreeValue }).create(\n\t\t\t\tinternal,\n\t\t\t);\n}\n\n/**\n * Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.\n * This slot is used to detect if one already exists and error if creating a second.\n * @remarks\n * See also {@link ContextSlot} in which the flex-tree context is stored.\n */\nexport const SimpleContextSlot = anchorSlot<HydratedContext>();\n"]}
@@ -2,12 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
6
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
7
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
8
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
9
- };
10
5
  var _UnhydratedFlexTreeNode_instances, _a, _UnhydratedFlexTreeNode_emitDeepChangesToAncestorArrays, _UnhydratedFlexTreeNode_emitSubtreeChangedEvents, _b, _c;
6
+ import { __classPrivateFieldGet } from "tslib";
11
7
  import { createEmitter } from "@fluid-internal/client-utils";
12
8
  import { assert, oob, fail } from "@fluidframework/core-utils/internal";
13
9
  import { UsageError } from "@fluidframework/telemetry-utils/internal";