@fluidframework/tree 2.70.0-361248 → 2.70.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 (222) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/api-report/tree.alpha.api.md +36 -17
  3. package/api-report/tree.beta.api.md +70 -2
  4. package/api-report/tree.legacy.beta.api.md +70 -2
  5. package/dist/alpha.d.ts +15 -11
  6. package/dist/api.d.ts +6 -1
  7. package/dist/api.d.ts.map +1 -1
  8. package/dist/api.js +9 -1
  9. package/dist/api.js.map +1 -1
  10. package/dist/beta.d.ts +13 -0
  11. package/dist/core/forest/forest.d.ts +3 -4
  12. package/dist/core/forest/forest.d.ts.map +1 -1
  13. package/dist/core/forest/forest.js.map +1 -1
  14. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +6 -0
  15. package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  16. package/dist/feature-libraries/chunked-forest/chunkTree.js +11 -2
  17. package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  18. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -1
  19. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  20. package/dist/feature-libraries/chunked-forest/chunkedForest.js +1 -1
  21. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  22. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +21 -20
  23. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  24. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +17 -43
  25. package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  26. package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
  27. package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  28. package/dist/feature-libraries/chunked-forest/index.js +2 -1
  29. package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
  30. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  31. package/dist/feature-libraries/flex-tree/lazyField.js +2 -1
  32. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  33. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
  34. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  35. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +43 -48
  36. package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  37. package/dist/feature-libraries/index.d.ts +1 -1
  38. package/dist/feature-libraries/index.d.ts.map +1 -1
  39. package/dist/feature-libraries/index.js +2 -1
  40. package/dist/feature-libraries/index.js.map +1 -1
  41. package/dist/feature-libraries/object-forest/objectForest.d.ts +1 -1
  42. package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  43. package/dist/feature-libraries/object-forest/objectForest.js +1 -1
  44. package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
  45. package/dist/index.d.ts +2 -2
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +4 -2
  48. package/dist/index.js.map +1 -1
  49. package/dist/legacy.d.ts +13 -0
  50. package/dist/packageVersion.d.ts +1 -1
  51. package/dist/packageVersion.d.ts.map +1 -1
  52. package/dist/packageVersion.js +1 -1
  53. package/dist/packageVersion.js.map +1 -1
  54. package/dist/shared-tree/independentView.d.ts.map +1 -1
  55. package/dist/shared-tree/independentView.js +2 -1
  56. package/dist/shared-tree/independentView.js.map +1 -1
  57. package/dist/shared-tree/schematizingTreeView.d.ts +4 -3
  58. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  59. package/dist/shared-tree/schematizingTreeView.js +1 -1
  60. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  61. package/dist/shared-tree/treeAlpha.d.ts +28 -2
  62. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  63. package/dist/shared-tree/treeAlpha.js +12 -0
  64. package/dist/shared-tree/treeAlpha.js.map +1 -1
  65. package/dist/shared-tree-core/sharedTreeCore.js +1 -1
  66. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  67. package/dist/simple-tree/api/incrementalAllowedTypes.d.ts +47 -0
  68. package/dist/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -0
  69. package/dist/simple-tree/api/incrementalAllowedTypes.js +90 -0
  70. package/dist/simple-tree/api/incrementalAllowedTypes.js.map +1 -0
  71. package/dist/simple-tree/api/index.d.ts +2 -1
  72. package/dist/simple-tree/api/index.d.ts.map +1 -1
  73. package/dist/simple-tree/api/index.js +4 -1
  74. package/dist/simple-tree/api/index.js.map +1 -1
  75. package/dist/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
  76. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  77. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  78. package/dist/simple-tree/api/tree.d.ts +51 -37
  79. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  80. package/dist/simple-tree/api/tree.js.map +1 -1
  81. package/dist/simple-tree/core/allowedTypes.d.ts +10 -11
  82. package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
  83. package/dist/simple-tree/core/allowedTypes.js +1 -1
  84. package/dist/simple-tree/core/allowedTypes.js.map +1 -1
  85. package/dist/simple-tree/core/index.d.ts +1 -1
  86. package/dist/simple-tree/core/index.d.ts.map +1 -1
  87. package/dist/simple-tree/core/index.js +2 -1
  88. package/dist/simple-tree/core/index.js.map +1 -1
  89. package/dist/simple-tree/core/withType.d.ts +20 -0
  90. package/dist/simple-tree/core/withType.d.ts.map +1 -1
  91. package/dist/simple-tree/core/withType.js +21 -1
  92. package/dist/simple-tree/core/withType.js.map +1 -1
  93. package/dist/simple-tree/index.d.ts +2 -2
  94. package/dist/simple-tree/index.d.ts.map +1 -1
  95. package/dist/simple-tree/index.js +5 -2
  96. package/dist/simple-tree/index.js.map +1 -1
  97. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +1 -0
  98. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  99. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +12 -0
  100. package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  101. package/lib/alpha.d.ts +15 -11
  102. package/lib/api.d.ts +6 -1
  103. package/lib/api.d.ts.map +1 -1
  104. package/lib/api.js +7 -0
  105. package/lib/api.js.map +1 -1
  106. package/lib/beta.d.ts +13 -0
  107. package/lib/core/forest/forest.d.ts +3 -4
  108. package/lib/core/forest/forest.d.ts.map +1 -1
  109. package/lib/core/forest/forest.js.map +1 -1
  110. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +6 -0
  111. package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
  112. package/lib/feature-libraries/chunked-forest/chunkTree.js +8 -0
  113. package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
  114. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +1 -1
  115. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  116. package/lib/feature-libraries/chunked-forest/chunkedForest.js +2 -2
  117. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  118. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +21 -20
  119. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
  120. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +17 -43
  121. package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
  122. package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
  123. package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
  124. package/lib/feature-libraries/chunked-forest/index.js +1 -1
  125. package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
  126. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  127. package/lib/feature-libraries/flex-tree/lazyField.js +2 -1
  128. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  129. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
  130. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
  131. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +43 -48
  132. package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
  133. package/lib/feature-libraries/index.d.ts +1 -1
  134. package/lib/feature-libraries/index.d.ts.map +1 -1
  135. package/lib/feature-libraries/index.js +1 -1
  136. package/lib/feature-libraries/index.js.map +1 -1
  137. package/lib/feature-libraries/object-forest/objectForest.d.ts +1 -1
  138. package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
  139. package/lib/feature-libraries/object-forest/objectForest.js +2 -2
  140. package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
  141. package/lib/index.d.ts +2 -2
  142. package/lib/index.d.ts.map +1 -1
  143. package/lib/index.js +2 -2
  144. package/lib/index.js.map +1 -1
  145. package/lib/legacy.d.ts +13 -0
  146. package/lib/packageVersion.d.ts +1 -1
  147. package/lib/packageVersion.d.ts.map +1 -1
  148. package/lib/packageVersion.js +1 -1
  149. package/lib/packageVersion.js.map +1 -1
  150. package/lib/shared-tree/independentView.d.ts.map +1 -1
  151. package/lib/shared-tree/independentView.js +2 -1
  152. package/lib/shared-tree/independentView.js.map +1 -1
  153. package/lib/shared-tree/schematizingTreeView.d.ts +4 -3
  154. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  155. package/lib/shared-tree/schematizingTreeView.js +2 -2
  156. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  157. package/lib/shared-tree/treeAlpha.d.ts +28 -2
  158. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  159. package/lib/shared-tree/treeAlpha.js +13 -1
  160. package/lib/shared-tree/treeAlpha.js.map +1 -1
  161. package/lib/shared-tree-core/sharedTreeCore.js +1 -1
  162. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  163. package/lib/simple-tree/api/incrementalAllowedTypes.d.ts +47 -0
  164. package/lib/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -0
  165. package/lib/simple-tree/api/incrementalAllowedTypes.js +86 -0
  166. package/lib/simple-tree/api/incrementalAllowedTypes.js.map +1 -0
  167. package/lib/simple-tree/api/index.d.ts +2 -1
  168. package/lib/simple-tree/api/index.d.ts.map +1 -1
  169. package/lib/simple-tree/api/index.js +1 -0
  170. package/lib/simple-tree/api/index.js.map +1 -1
  171. package/lib/simple-tree/api/schemaFactoryBeta.d.ts +2 -2
  172. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  173. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  174. package/lib/simple-tree/api/tree.d.ts +51 -37
  175. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  176. package/lib/simple-tree/api/tree.js.map +1 -1
  177. package/lib/simple-tree/core/allowedTypes.d.ts +10 -11
  178. package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
  179. package/lib/simple-tree/core/allowedTypes.js +1 -1
  180. package/lib/simple-tree/core/allowedTypes.js.map +1 -1
  181. package/lib/simple-tree/core/index.d.ts +1 -1
  182. package/lib/simple-tree/core/index.d.ts.map +1 -1
  183. package/lib/simple-tree/core/index.js +1 -1
  184. package/lib/simple-tree/core/index.js.map +1 -1
  185. package/lib/simple-tree/core/withType.d.ts +20 -0
  186. package/lib/simple-tree/core/withType.d.ts.map +1 -1
  187. package/lib/simple-tree/core/withType.js +20 -0
  188. package/lib/simple-tree/core/withType.js.map +1 -1
  189. package/lib/simple-tree/index.d.ts +2 -2
  190. package/lib/simple-tree/index.d.ts.map +1 -1
  191. package/lib/simple-tree/index.js +2 -2
  192. package/lib/simple-tree/index.js.map +1 -1
  193. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +1 -0
  194. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
  195. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +13 -1
  196. package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
  197. package/package.json +21 -21
  198. package/src/api.ts +11 -0
  199. package/src/core/forest/forest.ts +3 -4
  200. package/src/feature-libraries/chunked-forest/chunkTree.ts +9 -0
  201. package/src/feature-libraries/chunked-forest/chunkedForest.ts +3 -3
  202. package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +20 -58
  203. package/src/feature-libraries/chunked-forest/index.ts +1 -0
  204. package/src/feature-libraries/flex-tree/lazyField.ts +3 -1
  205. package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +65 -71
  206. package/src/feature-libraries/index.ts +1 -0
  207. package/src/feature-libraries/object-forest/objectForest.ts +3 -3
  208. package/src/index.ts +4 -1
  209. package/src/packageVersion.ts +1 -1
  210. package/src/shared-tree/independentView.ts +4 -1
  211. package/src/shared-tree/schematizingTreeView.ts +10 -5
  212. package/src/shared-tree/treeAlpha.ts +50 -2
  213. package/src/shared-tree-core/sharedTreeCore.ts +1 -1
  214. package/src/simple-tree/api/incrementalAllowedTypes.ts +107 -0
  215. package/src/simple-tree/api/index.ts +6 -0
  216. package/src/simple-tree/api/schemaFactoryBeta.ts +6 -2
  217. package/src/simple-tree/api/tree.ts +64 -44
  218. package/src/simple-tree/core/allowedTypes.ts +10 -11
  219. package/src/simple-tree/core/index.ts +6 -1
  220. package/src/simple-tree/core/withType.ts +24 -0
  221. package/src/simple-tree/index.ts +5 -0
  222. package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +13 -0
@@ -44,6 +44,7 @@ import {
44
44
  import { createTreeCheckout } from "./treeCheckout.js";
45
45
  import { SchematizingSimpleTreeView } from "./schematizingTreeView.js";
46
46
  import { initialize, initializerFromChunk } from "./schematizeTree.js";
47
+ import { combineChunks } from "../feature-libraries/index.js";
47
48
 
48
49
  /**
49
50
  * Create an uninitialized {@link TreeView} that is not tied to any {@link ITree} instance.
@@ -158,7 +159,9 @@ export function independentInitializedViewInternal<const TSchema extends Implici
158
159
  initialize(
159
160
  checkout,
160
161
  schema,
161
- initializerFromChunk(checkout, () => checkout.forest.chunkField(rootFieldCursor)),
162
+ initializerFromChunk(checkout, () =>
163
+ combineChunks(checkout.forest.chunkField(rootFieldCursor)),
164
+ ),
162
165
  );
163
166
  return new SchematizingSimpleTreeView<TSchema>(
164
167
  checkout,
@@ -19,6 +19,7 @@ import {
19
19
  cursorForMapTreeField,
20
20
  TreeStatus,
21
21
  Context,
22
+ combineChunks,
22
23
  type FlexTreeOptionalField,
23
24
  type FlexTreeUnknownUnboxed,
24
25
  FieldKinds,
@@ -70,6 +71,7 @@ import {
70
71
 
71
72
  import { canInitialize, initialize, initializerFromChunk } from "./schematizeTree.js";
72
73
  import type { ITreeCheckout, TreeCheckout } from "./treeCheckout.js";
74
+ import type { TreeBranchAlpha } from "../simple-tree/index.js";
73
75
 
74
76
  /**
75
77
  * Creating multiple tree views from the same checkout is not supported. This slot is used to detect if one already
@@ -227,8 +229,10 @@ export class SchematizingSimpleTreeView<
227
229
  schema,
228
230
  initializerFromChunk(this.checkout, () => {
229
231
  // This must be done after initial schema is set!
230
- return this.checkout.forest.chunkField(
231
- cursorForMapTreeField(mapTree === undefined ? [] : [mapTree]),
232
+ return combineChunks(
233
+ this.checkout.forest.chunkField(
234
+ cursorForMapTreeField(mapTree === undefined ? [] : [mapTree]),
235
+ ),
232
236
  );
233
237
  }),
234
238
  );
@@ -510,15 +514,16 @@ export class SchematizingSimpleTreeView<
510
514
 
511
515
  // #region Branching
512
516
 
513
- public fork(): ReturnType<TreeBranch["fork"]> & SchematizingSimpleTreeView<TRootSchema> {
517
+ public fork(): ReturnType<TreeBranchAlpha["fork"]> &
518
+ SchematizingSimpleTreeView<TRootSchema> {
514
519
  return this.checkout.branch().viewWith(this.config);
515
520
  }
516
521
 
517
- public merge(context: TreeBranch, disposeMerged = true): void {
522
+ public merge(context: TreeBranchAlpha, disposeMerged = true): void {
518
523
  this.checkout.merge(getCheckout(context), disposeMerged);
519
524
  }
520
525
 
521
- public rebaseOnto(context: TreeBranch): void {
526
+ public rebaseOnto(context: TreeBranchAlpha): void {
522
527
  getCheckout(context).rebase(this.checkout);
523
528
  }
524
529
 
@@ -58,6 +58,8 @@ import {
58
58
  importConcise,
59
59
  exportConcise,
60
60
  borrowCursorFromTreeNodeOrValue,
61
+ contentSchemaSymbol,
62
+ type TreeNodeSchema,
61
63
  } from "../simple-tree/index.js";
62
64
  import { brand, extractFromOpaque, type JsonCompatible } from "../util/index.js";
63
65
  import {
@@ -83,8 +85,10 @@ import {
83
85
  type Observer,
84
86
  withObservation,
85
87
  } from "../feature-libraries/index.js";
88
+ import type { TreeBranchAlpha } from "../simple-tree/index.js";
86
89
  import { independentInitializedView, type ViewContent } from "./independentView.js";
87
90
  import { SchematizingSimpleTreeView, ViewSlot } from "./schematizingTreeView.js";
91
+ import { isFluidHandle } from "@fluidframework/runtime-utils";
88
92
 
89
93
  const identifier: TreeIdentifierUtils = (node: TreeNode): string | undefined => {
90
94
  const nodeIdentifier = getIdentifierFromNode(node, "uncompressed");
@@ -227,7 +231,7 @@ export interface TreeAlpha {
227
231
  * This does not fork a new branch, but rather retrieves the _existing_ branch for the node.
228
232
  * To create a new branch, use e.g. {@link TreeBranch.fork | `myBranch.fork()`}.
229
233
  */
230
- branch(node: TreeNode): TreeBranch | undefined;
234
+ branch(node: TreeNode): TreeBranchAlpha | undefined;
231
235
 
232
236
  /**
233
237
  * Construct tree content that is compatible with the field defined by the provided `schema`.
@@ -519,6 +523,35 @@ export interface TreeAlpha {
519
523
  onInvalidation: () => void,
520
524
  trackDuring: () => TResult,
521
525
  ): ObservationResults<TResult>;
526
+
527
+ /**
528
+ * Ensures that the provided content will be interpreted as the given schema when inserting into the tree.
529
+ * @returns `content`, for convenience.
530
+ * @remarks
531
+ * If applicable, this will tag the given content with a {@link contentSchemaSymbol | special property} that indicates its intended schema.
532
+ * The `content` will be interpreted as the given `schema` when later inserted into the tree.
533
+ *
534
+ * This does not validate that the content actually conforms to the given schema (such validation will be done at insert time).
535
+ * If the content is not compatible with the tagged schema, an error will be thrown when the content is inserted.
536
+ *
537
+ * This is particularly useful when the content's schema cannot be inferred from its structure alone because it is compatible with multiple schemas.
538
+ * @example
539
+ * ```typescript
540
+ * const sf = new SchemaFactory("example");
541
+ * class Dog extends sf.object("Dog", { name: sf.string() }) {}
542
+ * class Cat extends sf.object("Cat", { name: sf.string() }) {}
543
+ * class Root extends sf.object("Root", { pet: [Dog, Cat] }) {}
544
+ * // ...
545
+ * const pet = { name: "Max" };
546
+ * view.root.pet = pet; // Error: ambiguous schema - is it a Dog or a Cat?
547
+ * TreeAlpha.ensureSchema(Dog, pet); // Tags `pet` as a Dog.
548
+ * view.root.pet = pet; // No error - it's a Dog.
549
+ * ```
550
+ */
551
+ tagContentSchema<TSchema extends TreeNodeSchema, TContent extends InsertableField<TSchema>>(
552
+ schema: TSchema,
553
+ content: TContent,
554
+ ): TContent;
522
555
  }
523
556
 
524
557
  /**
@@ -723,7 +756,7 @@ export const TreeAlpha: TreeAlpha = {
723
756
  return result;
724
757
  },
725
758
 
726
- branch(node: TreeNode): TreeBranch | undefined {
759
+ branch(node: TreeNode): TreeBranchAlpha | undefined {
727
760
  const kernel = getKernel(node);
728
761
  if (!kernel.isHydrated()) {
729
762
  return undefined;
@@ -1003,6 +1036,21 @@ export const TreeAlpha: TreeAlpha = {
1003
1036
  }
1004
1037
  return result;
1005
1038
  },
1039
+
1040
+ tagContentSchema<TSchema extends TreeNodeSchema, TNode extends InsertableField<TSchema>>(
1041
+ schema: TSchema,
1042
+ node: TNode,
1043
+ ): TNode {
1044
+ if (typeof node === "object" && node !== null && !isFluidHandle(node)) {
1045
+ Reflect.defineProperty(node, contentSchemaSymbol, {
1046
+ configurable: false,
1047
+ enumerable: false,
1048
+ writable: true,
1049
+ value: schema.identifier,
1050
+ });
1051
+ }
1052
+ return node;
1053
+ },
1006
1054
  };
1007
1055
 
1008
1056
  /**
@@ -719,7 +719,7 @@ function scopeStorageService(
719
719
  return service.list(`${scope}${path}`);
720
720
  },
721
721
  getSnapshotTree(): ISnapshotTree | undefined {
722
- const snapshotTree = service.getSnapshotTree?.();
722
+ const snapshotTree = service.getSnapshotTree();
723
723
  if (snapshotTree === undefined) {
724
724
  return undefined;
725
725
  }
@@ -0,0 +1,107 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type { FieldKey, TreeNodeSchemaIdentifier } from "../../core/index.js";
7
+ import { getTreeNodeSchemaPrivateData, type AllowedTypesFull } from "../core/index.js";
8
+ import { isObjectNodeSchema } from "../node-kinds/index.js";
9
+ import type { TreeSchema } from "./configuration.js";
10
+ import type { IncrementalEncodingPolicy } from "../../feature-libraries/index.js";
11
+ import { oneFromIterable } from "../../util/index.js";
12
+ import { assert } from "@fluidframework/core-utils/internal";
13
+
14
+ /**
15
+ * A symbol when present in the {@link AnnotatedAllowedTypes.metadata.custom} property as true, opts in the allowed
16
+ * types to incremental summary optimization.
17
+ * These allowed types will be optimized during summary such that if they don't change across summaries,
18
+ * they will not be encoded and their content will not be included in the summary that is uploaded to the service.
19
+ * @remarks
20
+ * See {@link getShouldIncrementallySummarizeAllowedTypes} for more details.
21
+ *
22
+ * Use {@link SchemaStaticsAlpha.types} to add this metadata to allowed types in a schema.
23
+ * @example
24
+ * ```typescript
25
+ * const sf = new SchemaFactoryAlpha("IncrementalSummarization");
26
+ * class Foo extends sf.objectAlpha("foo", {
27
+ * bar: sf.types([{ type: sf.string, metadata: {} }], {
28
+ * custom: { [incrementalSummaryHint]: true },
29
+ * }),
30
+ * }) {}
31
+ * ```
32
+ */
33
+ export const incrementalSummaryHint: unique symbol = Symbol("IncrementalSummaryHint");
34
+
35
+ /**
36
+ * Returns true if the provided allowed types's custom metadata has {@link incrementalSummaryHint} as true.
37
+ */
38
+ function isIncrementalSummaryHintInAllowedTypes(allowedTypes: AllowedTypesFull): boolean {
39
+ const customMetadata = allowedTypes.metadata.custom;
40
+ return (
41
+ customMetadata !== undefined &&
42
+ (customMetadata as Record<symbol, unknown>)[incrementalSummaryHint] === true
43
+ );
44
+ }
45
+
46
+ /**
47
+ * This helper function {@link getShouldIncrementallySummarizeAllowedTypes} can be used to generate a callback function
48
+ * of type {@link IncrementalEncodingPolicy}.
49
+ * This callback can be passed as the value for {@link SharedTreeOptionsInternal.shouldEncodeFieldIncrementally} parameter
50
+ * when creating the tree.
51
+ * It will be called for each {@link AllowedTypes} in the schema to determine if it should be incrementally summarized.
52
+ *
53
+ * @param rootSchema - The schema for the root of the tree.
54
+ * @returns A callback function of type {@link IncrementalEncodingPolicy} which can be used to determine if a field
55
+ * should be incrementally summarized based on whether it is an allowed types with the
56
+ * {@link incrementalAllowedTypesMetadata} metadata.
57
+ *
58
+ * @remarks
59
+ * This only works for forest type {@link ForestTypeOptimized} and compression strategy
60
+ * {@link TreeCompressionStrategyExtended.CompressedIncremental}.
61
+ *
62
+ * The {@link incrementalAllowedTypesMetadata} will be replaced with a specialized metadata property once the
63
+ * incremental summary feature and APIs are stabilized.
64
+ */
65
+ export function getShouldIncrementallySummarizeAllowedTypes(
66
+ rootSchema: TreeSchema,
67
+ ): IncrementalEncodingPolicy {
68
+ return (
69
+ targetNodeIdentifier: TreeNodeSchemaIdentifier | undefined,
70
+ targetFieldKey: FieldKey,
71
+ ) => {
72
+ if (targetNodeIdentifier === undefined) {
73
+ // Root fields cannot be allowed types, so we don't incrementally summarize them.
74
+ return false;
75
+ }
76
+
77
+ const targetNode = rootSchema.definitions.get(targetNodeIdentifier);
78
+ if (targetNode === undefined) {
79
+ // The requested type is unknown to this schema.
80
+ // In this case we have no hints available from the view schema, and fall back to the default behavior of non-incremental encoding.
81
+ // There are two ways this can happen:
82
+ // 1. The view schema being used does not match the stored schema.
83
+ // 2. The view schema is compatible, but there are unknown optional fields which contain new types not described by the view schema.
84
+ return false;
85
+ }
86
+
87
+ if (isObjectNodeSchema(targetNode)) {
88
+ const targetPropertyKey = targetNode.storedKeyToPropertyKey.get(targetFieldKey);
89
+ if (targetPropertyKey !== undefined) {
90
+ const fieldSchema = targetNode.fields.get(targetPropertyKey);
91
+ if (fieldSchema !== undefined) {
92
+ return isIncrementalSummaryHintInAllowedTypes(fieldSchema.allowedTypesFull);
93
+ }
94
+ }
95
+ return false;
96
+ }
97
+
98
+ const allowedTypes = oneFromIterable(
99
+ getTreeNodeSchemaPrivateData(targetNode).childAllowedTypes,
100
+ );
101
+ assert(
102
+ allowedTypes !== undefined,
103
+ 0xc87 /* Non object nodes with fields should only have one allowedTypes entry */,
104
+ );
105
+ return isIncrementalSummaryHintInAllowedTypes(allowedTypes);
106
+ };
107
+ }
@@ -19,7 +19,9 @@ export type {
19
19
  TreeViewEvents,
20
20
  SchemaCompatibilityStatus,
21
21
  TreeViewAlpha,
22
+ TreeViewBeta,
22
23
  TreeBranch,
24
+ TreeBranchAlpha,
23
25
  TreeBranchEvents,
24
26
  ITreeAlpha,
25
27
  } from "./tree.js";
@@ -161,3 +163,7 @@ export {
161
163
  export { generateSchemaFromSimpleSchema } from "./schemaFromSimple.js";
162
164
  export { toSimpleTreeSchema } from "./viewSchemaToSimpleSchema.js";
163
165
  export type { TreeChangeEvents } from "./treeChangeEvents.js";
166
+ export {
167
+ getShouldIncrementallySummarizeAllowedTypes,
168
+ incrementalSummaryHint,
169
+ } from "./incrementalAllowedTypes.js";
@@ -88,7 +88,9 @@ export class SchemaFactoryBeta<
88
88
  TreeObjectNode<T, ScopedSchemaName<TScope, Name>>,
89
89
  object & InsertableObjectFromSchemaRecord<T>,
90
90
  true,
91
- T
91
+ T,
92
+ never,
93
+ TCustomMetadata
92
94
  > {
93
95
  return objectSchema(scoped<TScope, TName, Name>(this, name), fields, true, {
94
96
  ...defaultSchemaFactoryObjectOptions,
@@ -110,7 +112,9 @@ export class SchemaFactoryBeta<
110
112
  System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>,
111
113
  object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>,
112
114
  false,
113
- T
115
+ T,
116
+ never,
117
+ TCustomMetadata
114
118
  > {
115
119
  type TScopedName = ScopedSchemaName<TScope, Name>;
116
120
  return this.object(
@@ -126,37 +126,10 @@ export interface ITreeAlpha extends ITree {
126
126
  * A collection of functionality associated with a (version-control-style) branch of a SharedTree.
127
127
  * @remarks A `TreeBranch` allows for the {@link TreeBranch.fork | creation of branches} and for those branches to later be {@link TreeBranch.merge | merged}.
128
128
  *
129
- * The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.
130
- *
131
- * 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 TreeBranch.hasRootSchema | hasRootSchema()}.
132
- *
133
129
  * 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.
134
- * @sealed @alpha
130
+ * @sealed @beta
135
131
  */
136
132
  export interface TreeBranch extends IDisposable {
137
- /**
138
- * Events for the branch
139
- */
140
- readonly events: Listenable<TreeBranchEvents>;
141
-
142
- /**
143
- * Returns true if this branch has the given schema as its root schema.
144
- * @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.
145
- *
146
- * To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.
147
- * 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`.
148
- * @example
149
- * ```typescript
150
- * if (branch.hasRootSchema(MySchema)) {
151
- * const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>
152
- * // ...
153
- * }
154
- * ```
155
- */
156
- hasRootSchema<TSchema extends ImplicitFieldSchema>(
157
- schema: TSchema,
158
- ): this is TreeViewAlpha<TSchema>;
159
-
160
133
  /**
161
134
  * Fork a new branch off of this branch which is based off of this branch's current state.
162
135
  * @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.
@@ -187,6 +160,54 @@ export interface TreeBranch extends IDisposable {
187
160
  */
188
161
  rebaseOnto(branch: TreeBranch): void;
189
162
 
163
+ /**
164
+ * Dispose of this branch, cleaning up any resources associated with it.
165
+ * @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.
166
+ * @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.
167
+ *
168
+ * Disposing branches is important to avoid consuming memory unnecessarily.
169
+ * 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}.
170
+ *
171
+ * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.
172
+ */
173
+ dispose(error?: Error): void;
174
+ }
175
+
176
+ /**
177
+ * {@link TreeBranch} with alpha-level APIs.
178
+ * @remarks
179
+ * The `TreeBranch` for a specific {@link TreeNode} may be acquired by calling `TreeAlpha.branch`.
180
+ *
181
+ * 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()}.
182
+ * @sealed @alpha
183
+ */
184
+ export interface TreeBranchAlpha extends TreeBranch {
185
+ /**
186
+ * Events for the branch
187
+ */
188
+ readonly events: Listenable<TreeBranchEvents>;
189
+
190
+ /**
191
+ * Returns true if this branch has the given schema as its root schema.
192
+ * @remarks This is a type guard which allows this branch to become strongly typed as a {@link TreeViewAlpha | view} of the given schema.
193
+ *
194
+ * To succeed, the given schema must be invariant to the schema of the view - it must include exactly the same allowed types.
195
+ * 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`.
196
+ * @example
197
+ * ```typescript
198
+ * if (branch.hasRootSchema(MySchema)) {
199
+ * const { root } = branch; // `branch` is now a TreeViewAlpha<MySchema>
200
+ * // ...
201
+ * }
202
+ * ```
203
+ */
204
+ hasRootSchema<TSchema extends ImplicitFieldSchema>(
205
+ schema: TSchema,
206
+ ): this is TreeViewAlpha<TSchema>;
207
+
208
+ // Override the base fork method to return the alpha variant.
209
+ fork(): TreeBranchAlpha;
210
+
190
211
  /**
191
212
  * Run a transaction which applies one or more edits to the tree as a single atomic unit.
192
213
  * @param transaction - The function to run as the body of the transaction.
@@ -261,18 +282,6 @@ export interface TreeBranch extends IDisposable {
261
282
  transaction: () => VoidTransactionCallbackStatus | void,
262
283
  params?: RunTransactionParams,
263
284
  ): TransactionResult;
264
-
265
- /**
266
- * Dispose of this branch, cleaning up any resources associated with it.
267
- * @param error - Optional error indicating the reason for the disposal, if the object was disposed as the result of an error.
268
- * @remarks Branches can also be automatically disposed when {@link TreeBranch.merge | they are merged} into another branch.
269
- *
270
- * Disposing branches is important to avoid consuming memory unnecessarily.
271
- * 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}.
272
- *
273
- * The {@link TreeBranch | main branch} cannot be disposed - attempting to do so will have no effect.
274
- */
275
- dispose(error?: Error): void;
276
285
  }
277
286
 
278
287
  /**
@@ -371,18 +380,29 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
371
380
  */
372
381
  export interface TreeViewAlpha<
373
382
  in out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,
374
- > extends Omit<TreeView<ReadSchema<TSchema>>, "root" | "initialize">,
375
- TreeBranch {
383
+ > extends Omit<TreeViewBeta<ReadSchema<TSchema>>, "root" | "initialize" | "fork">,
384
+ TreeBranchAlpha {
376
385
  get root(): ReadableField<TSchema>;
377
386
 
378
387
  set root(newRoot: InsertableField<TSchema>);
379
388
 
389
+ initialize(content: InsertableField<TSchema>): void;
390
+
380
391
  readonly events: Listenable<TreeViewEvents & TreeBranchEvents>;
381
392
 
382
- initialize(content: InsertableField<TSchema>): void;
393
+ // Override the base fork method to return a TreeViewAlpha.
394
+ fork(): ReturnType<TreeBranch["fork"]> & TreeViewAlpha<TSchema>;
395
+ }
383
396
 
397
+ /**
398
+ * {@link TreeView} with additional beta APIs.
399
+ * @sealed @beta
400
+ */
401
+ export interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema>
402
+ extends TreeView<TSchema>,
403
+ TreeBranch {
384
404
  // Override the base branch method to return a typed view rather than merely a branch.
385
- fork(): ReturnType<TreeBranch["fork"]> & TreeViewAlpha<TSchema>;
405
+ fork(): ReturnType<TreeBranch["fork"]> & TreeViewBeta<TSchema>;
386
406
  }
387
407
 
388
408
  /**
@@ -60,7 +60,7 @@ export type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
60
60
  * @privateRemarks
61
61
  * Since this is sealed, users are not supposed to create instances of it directly.
62
62
  * Making it extend ErasedType could enforce that.
63
- * @alpha
63
+ * @beta
64
64
  * @sealed
65
65
  */
66
66
  export interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {
@@ -77,7 +77,7 @@ export interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {
77
77
  /**
78
78
  * {@link AllowedTypesFull} but with the lazy schema references eagerly evaluated.
79
79
  * @sealed
80
- * @alpha
80
+ * @beta
81
81
  */
82
82
  export type AllowedTypesFullEvaluated = AllowedTypesFull<
83
83
  readonly AnnotatedAllowedType<TreeNodeSchema>[]
@@ -95,7 +95,7 @@ export function isAnnotatedAllowedTypes(
95
95
 
96
96
  /**
97
97
  * Stores annotations for a set of allowed types.
98
- * @alpha
98
+ * @beta
99
99
  * @sealed
100
100
  */
101
101
  export interface AnnotatedAllowedTypes<T = readonly AnnotatedAllowedType[]>
@@ -139,7 +139,7 @@ export interface AnnotatedAllowedTypes<T = readonly AnnotatedAllowedType[]>
139
139
  * Stores annotations for a set of allowed types.
140
140
  * @remarks
141
141
  * Most expressive form of AllowedTypes which any of the implicit types can be normalized to.
142
- * @alpha
142
+ * @beta
143
143
  * @sealed
144
144
  */
145
145
  export type AllowedTypesFull<
@@ -148,8 +148,7 @@ export type AllowedTypesFull<
148
148
 
149
149
  /**
150
150
  * Creates an {@link AllowedTypesFull} type from a mixed array of annotated and unannotated allowed types.
151
- * @alpha
152
- * @sealed
151
+ * @system @sealed @beta
153
152
  */
154
153
  export type AllowedTypesFullFromMixed<
155
154
  T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],
@@ -360,7 +359,7 @@ export class AnnotatedAllowedTypesInternal<
360
359
  * Annotations that apply to a set of allowed types.
361
360
  * @remarks
362
361
  * Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.
363
- * @alpha
362
+ * @beta
364
363
  * @input
365
364
  */
366
365
  export interface AllowedTypesMetadata {
@@ -385,7 +384,7 @@ export function isAnnotatedAllowedType(
385
384
  * Annotations that apply to an individual allowed type.
386
385
  * @remarks
387
386
  * Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.
388
- * @alpha
387
+ * @beta
389
388
  * @input
390
389
  */
391
390
  export interface AllowedTypeMetadata {
@@ -413,7 +412,7 @@ export let createSchemaUpgrade: () => SchemaUpgrade;
413
412
  * TODO:#38722 implement runtime schema upgrades.
414
413
  * Until then, the class purely behaves mostly as a placeholder.
415
414
  * TODO: Consider allowing users to store a name for the upgrade to use in error messages.
416
- * @sealed @alpha
415
+ * @sealed @beta
417
416
  */
418
417
  export class SchemaUpgrade {
419
418
  protected _typeCheck!: MakeNominal;
@@ -461,7 +460,7 @@ export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;
461
460
 
462
461
  /**
463
462
  * Removes annotations from a list of allowed types that may contain annotations.
464
- * @system @alpha
463
+ * @system @beta
465
464
  */
466
465
  export type UnannotateAllowedTypesList<
467
466
  T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],
@@ -471,7 +470,7 @@ export type UnannotateAllowedTypesList<
471
470
 
472
471
  /**
473
472
  * Add annotations to a list of allowed types that may or may not contain annotations.
474
- * @system @alpha
473
+ * @system @beta
475
474
  */
476
475
  export type AnnotateAllowedTypesList<
477
476
  T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],
@@ -16,7 +16,12 @@ export {
16
16
  SimpleContextSlot,
17
17
  withBufferedTreeEvents,
18
18
  } from "./treeNodeKernel.js";
19
- export { type WithType, typeNameSymbol, typeSchemaSymbol } from "./withType.js";
19
+ export {
20
+ type WithType,
21
+ typeNameSymbol,
22
+ typeSchemaSymbol,
23
+ contentSchemaSymbol,
24
+ } from "./withType.js";
20
25
  export {
21
26
  type Unhydrated,
22
27
  type InternalTreeNode,
@@ -5,6 +5,9 @@
5
5
 
6
6
  import type { TreeNode } from "./treeNode.js";
7
7
  import type { NodeKind, TreeNodeSchemaClass } from "./treeNodeSchema.js";
8
+ // Used by doc links:
9
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports
10
+ import type { TreeAlpha } from "../../shared-tree/index.js";
8
11
 
9
12
  /**
10
13
  * The type of a {@link TreeNode}.
@@ -39,6 +42,27 @@ export const typeNameSymbol: unique symbol = Symbol("TreeNode Type");
39
42
  */
40
43
  export const typeSchemaSymbol: unique symbol = Symbol("TreeNode Schema");
41
44
 
45
+ /**
46
+ * The intended type of insertable content that is to become a {@link TreeNode}.
47
+ * @remarks Use the type-safe {@link (TreeAlpha:interface).tagContentSchema} function to tag insertable content with this symbol.
48
+ *
49
+ * If a property with this symbol key is present on an object that is inserted into the tree,
50
+ * the tree will use the schema identifier specified by the value of this property when creating the node.
51
+ * This is particularly useful for specifying the intended schema of untyped content when it would otherwise be ambiguous.
52
+ * @example
53
+ * ```typescript
54
+ * const sf = new SchemaFactory("example");
55
+ * class Dog extends sf.object("Dog", { name: sf.string() }) {}
56
+ * class Cat extends sf.object("Cat", { name: sf.string() }) {}
57
+ * class Root extends sf.object("Root", { pet: [Dog, Cat] }) {}
58
+ * // ...
59
+ * view.root.pet = { name: "Max" }; // Error: ambiguous schema - is it a Dog or a Cat?
60
+ * view.root.pet = { name: "Max", [contentSchemaSymbol]: "example.Dog" }; // No error - it's a Dog.
61
+ * ```
62
+ * @alpha
63
+ */
64
+ export const contentSchemaSymbol: unique symbol = Symbol("SharedTree Schema");
65
+
42
66
  /**
43
67
  * Adds a type symbol to a type for stronger typing.
44
68
  *
@@ -6,6 +6,7 @@
6
6
  export {
7
7
  typeNameSymbol,
8
8
  typeSchemaSymbol,
9
+ contentSchemaSymbol,
9
10
  type WithType,
10
11
  type TreeNodeSchema,
11
12
  type AnnotatedAllowedType,
@@ -135,7 +136,9 @@ export {
135
136
  type UnannotateAllowedTypesListUnsafe,
136
137
  type AnnotateAllowedTypesListUnsafe,
137
138
  type TreeViewAlpha,
139
+ type TreeViewBeta,
138
140
  type TreeBranch,
141
+ type TreeBranchAlpha,
139
142
  type TreeBranchEvents,
140
143
  getPropertyKeyFromStoredKey,
141
144
  getStoredKey,
@@ -180,6 +183,8 @@ export {
180
183
  type SchemaStaticsAlpha,
181
184
  KeyEncodingOptions,
182
185
  type TreeParsingOptions,
186
+ incrementalSummaryHint,
187
+ getShouldIncrementallySummarizeAllowedTypes,
183
188
  type SchemaFactory_base,
184
189
  } from "./api/index.js";
185
190
  export type {
@@ -17,6 +17,7 @@ import {
17
17
  isTreeNode,
18
18
  type TreeNode,
19
19
  type TreeNodeSchema,
20
+ contentSchemaSymbol,
20
21
  type Unhydrated,
21
22
  UnhydratedFlexTreeNode,
22
23
  } from "./core/index.js";
@@ -125,16 +126,28 @@ For class-based schema, this can be done by replacing an expression like "{foo:
125
126
 
126
127
  /**
127
128
  * Returns all types for which the data is schema-compatible.
129
+ * @remarks This will respect the {@link contentSchemaSymbol} property on data to disambiguate types - if present, only that type will be returned.
128
130
  */
129
131
  export function getPossibleTypes(
130
132
  allowedTypes: ReadonlySet<TreeNodeSchema>,
131
133
  data: FactoryContent,
132
134
  ): TreeNodeSchema[] {
133
135
  assert(data !== undefined, 0x889 /* undefined cannot be used as FactoryContent. */);
136
+ const type =
137
+ typeof data === "object" && data !== null
138
+ ? (data as Partial<{ [contentSchemaSymbol]: string }>)[contentSchemaSymbol]
139
+ : undefined;
134
140
 
135
141
  let best = CompatibilityLevel.None;
136
142
  const possibleTypes: TreeNodeSchema[] = [];
137
143
  for (const schema of allowedTypes) {
144
+ if (type !== undefined) {
145
+ if (schema.identifier === type) {
146
+ return [schema];
147
+ } else {
148
+ continue;
149
+ }
150
+ }
138
151
  const handler = getTreeNodeSchemaPrivateData(schema).idempotentInitialize();
139
152
  const level = handler.shallowCompatibilityTest(data);
140
153
  if (level > best) {