@fluidframework/tree 2.43.0-343119 → 2.43.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 (206) hide show
  1. package/CHANGELOG.md +189 -0
  2. package/api-report/tree.alpha.api.md +13 -4
  3. package/api-report/tree.beta.api.md +1 -0
  4. package/api-report/tree.legacy.alpha.api.md +1 -0
  5. package/api-report/tree.legacy.public.api.md +1 -0
  6. package/api-report/tree.public.api.md +1 -0
  7. package/dist/alpha.d.ts +1 -0
  8. package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -1
  9. package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/packageVersion.d.ts +1 -1
  14. package/dist/packageVersion.d.ts.map +1 -1
  15. package/dist/packageVersion.js +1 -1
  16. package/dist/packageVersion.js.map +1 -1
  17. package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
  18. package/dist/shared-tree/schematizingTreeView.js +3 -3
  19. package/dist/shared-tree/schematizingTreeView.js.map +1 -1
  20. package/dist/shared-tree/treeAlpha.d.ts +38 -0
  21. package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
  22. package/dist/shared-tree/treeAlpha.js +114 -9
  23. package/dist/shared-tree/treeAlpha.js.map +1 -1
  24. package/dist/simple-tree/api/configuration.d.ts +15 -3
  25. package/dist/simple-tree/api/configuration.d.ts.map +1 -1
  26. package/dist/simple-tree/api/configuration.js +40 -22
  27. package/dist/simple-tree/api/configuration.js.map +1 -1
  28. package/dist/simple-tree/api/index.d.ts +1 -1
  29. package/dist/simple-tree/api/index.d.ts.map +1 -1
  30. package/dist/simple-tree/api/index.js +4 -4
  31. package/dist/simple-tree/api/index.js.map +1 -1
  32. package/dist/simple-tree/api/treeNodeApi.d.ts +3 -0
  33. package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  34. package/dist/simple-tree/api/treeNodeApi.js +1 -1
  35. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  36. package/dist/simple-tree/core/context.d.ts +3 -3
  37. package/dist/simple-tree/core/context.d.ts.map +1 -1
  38. package/dist/simple-tree/core/context.js.map +1 -1
  39. package/dist/simple-tree/core/getOrCreateNode.d.ts +9 -0
  40. package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  41. package/dist/simple-tree/core/getOrCreateNode.js +12 -1
  42. package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
  43. package/dist/simple-tree/core/index.d.ts +2 -2
  44. package/dist/simple-tree/core/index.d.ts.map +1 -1
  45. package/dist/simple-tree/core/index.js +3 -1
  46. package/dist/simple-tree/core/index.js.map +1 -1
  47. package/dist/simple-tree/core/treeNodeKernel.js +1 -1
  48. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  49. package/dist/simple-tree/core/treeNodeSchema.d.ts +68 -1
  50. package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  51. package/dist/simple-tree/core/treeNodeSchema.js +24 -1
  52. package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
  53. package/dist/simple-tree/core/walkSchema.d.ts +3 -3
  54. package/dist/simple-tree/core/walkSchema.d.ts.map +1 -1
  55. package/dist/simple-tree/core/walkSchema.js +9 -5
  56. package/dist/simple-tree/core/walkSchema.js.map +1 -1
  57. package/dist/simple-tree/createContext.js +1 -1
  58. package/dist/simple-tree/createContext.js.map +1 -1
  59. package/dist/simple-tree/getTreeNodeForField.d.ts +1 -1
  60. package/dist/simple-tree/getTreeNodeForField.d.ts.map +1 -1
  61. package/dist/simple-tree/getTreeNodeForField.js +3 -3
  62. package/dist/simple-tree/getTreeNodeForField.js.map +1 -1
  63. package/dist/simple-tree/index.d.ts +5 -5
  64. package/dist/simple-tree/index.d.ts.map +1 -1
  65. package/dist/simple-tree/index.js +8 -5
  66. package/dist/simple-tree/index.js.map +1 -1
  67. package/dist/simple-tree/leafNodeSchema.d.ts +2 -1
  68. package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
  69. package/dist/simple-tree/leafNodeSchema.js +1 -0
  70. package/dist/simple-tree/leafNodeSchema.js.map +1 -1
  71. package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  72. package/dist/simple-tree/node-kinds/array/arrayNode.js +18 -15
  73. package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  74. package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  75. package/dist/simple-tree/node-kinds/map/mapNode.js +7 -3
  76. package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  77. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  78. package/dist/simple-tree/node-kinds/object/objectNode.js +9 -6
  79. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  80. package/dist/simple-tree/schemaTypes.d.ts +13 -27
  81. package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
  82. package/dist/simple-tree/schemaTypes.js +45 -39
  83. package/dist/simple-tree/schemaTypes.js.map +1 -1
  84. package/dist/simple-tree/toStoredSchema.d.ts +2 -0
  85. package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
  86. package/dist/simple-tree/toStoredSchema.js +2 -0
  87. package/dist/simple-tree/toStoredSchema.js.map +1 -1
  88. package/dist/simple-tree/treeNodeValid.d.ts.map +1 -1
  89. package/dist/simple-tree/treeNodeValid.js +1 -2
  90. package/dist/simple-tree/treeNodeValid.js.map +1 -1
  91. package/dist/simple-tree/walkFieldSchema.d.ts.map +1 -1
  92. package/dist/simple-tree/walkFieldSchema.js +1 -1
  93. package/dist/simple-tree/walkFieldSchema.js.map +1 -1
  94. package/lib/alpha.d.ts +1 -0
  95. package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -1
  96. package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
  97. package/lib/index.d.ts +1 -1
  98. package/lib/index.d.ts.map +1 -1
  99. package/lib/index.js.map +1 -1
  100. package/lib/packageVersion.d.ts +1 -1
  101. package/lib/packageVersion.d.ts.map +1 -1
  102. package/lib/packageVersion.js +1 -1
  103. package/lib/packageVersion.js.map +1 -1
  104. package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
  105. package/lib/shared-tree/schematizingTreeView.js +4 -4
  106. package/lib/shared-tree/schematizingTreeView.js.map +1 -1
  107. package/lib/shared-tree/treeAlpha.d.ts +38 -0
  108. package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
  109. package/lib/shared-tree/treeAlpha.js +108 -3
  110. package/lib/shared-tree/treeAlpha.js.map +1 -1
  111. package/lib/simple-tree/api/configuration.d.ts +15 -3
  112. package/lib/simple-tree/api/configuration.d.ts.map +1 -1
  113. package/lib/simple-tree/api/configuration.js +42 -24
  114. package/lib/simple-tree/api/configuration.js.map +1 -1
  115. package/lib/simple-tree/api/index.d.ts +1 -1
  116. package/lib/simple-tree/api/index.d.ts.map +1 -1
  117. package/lib/simple-tree/api/index.js +1 -1
  118. package/lib/simple-tree/api/index.js.map +1 -1
  119. package/lib/simple-tree/api/treeNodeApi.d.ts +3 -0
  120. package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
  121. package/lib/simple-tree/api/treeNodeApi.js +2 -2
  122. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  123. package/lib/simple-tree/core/context.d.ts +3 -3
  124. package/lib/simple-tree/core/context.d.ts.map +1 -1
  125. package/lib/simple-tree/core/context.js.map +1 -1
  126. package/lib/simple-tree/core/getOrCreateNode.d.ts +9 -0
  127. package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  128. package/lib/simple-tree/core/getOrCreateNode.js +10 -0
  129. package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
  130. package/lib/simple-tree/core/index.d.ts +2 -2
  131. package/lib/simple-tree/core/index.d.ts.map +1 -1
  132. package/lib/simple-tree/core/index.js +2 -2
  133. package/lib/simple-tree/core/index.js.map +1 -1
  134. package/lib/simple-tree/core/treeNodeKernel.js +1 -1
  135. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  136. package/lib/simple-tree/core/treeNodeSchema.d.ts +68 -1
  137. package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
  138. package/lib/simple-tree/core/treeNodeSchema.js +21 -0
  139. package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
  140. package/lib/simple-tree/core/walkSchema.d.ts +3 -3
  141. package/lib/simple-tree/core/walkSchema.d.ts.map +1 -1
  142. package/lib/simple-tree/core/walkSchema.js +9 -5
  143. package/lib/simple-tree/core/walkSchema.js.map +1 -1
  144. package/lib/simple-tree/createContext.js +1 -1
  145. package/lib/simple-tree/createContext.js.map +1 -1
  146. package/lib/simple-tree/getTreeNodeForField.d.ts +1 -1
  147. package/lib/simple-tree/getTreeNodeForField.d.ts.map +1 -1
  148. package/lib/simple-tree/getTreeNodeForField.js +1 -1
  149. package/lib/simple-tree/getTreeNodeForField.js.map +1 -1
  150. package/lib/simple-tree/index.d.ts +5 -5
  151. package/lib/simple-tree/index.d.ts.map +1 -1
  152. package/lib/simple-tree/index.js +4 -4
  153. package/lib/simple-tree/index.js.map +1 -1
  154. package/lib/simple-tree/leafNodeSchema.d.ts +2 -1
  155. package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
  156. package/lib/simple-tree/leafNodeSchema.js +2 -1
  157. package/lib/simple-tree/leafNodeSchema.js.map +1 -1
  158. package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
  159. package/lib/simple-tree/node-kinds/array/arrayNode.js +10 -7
  160. package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
  161. package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
  162. package/lib/simple-tree/node-kinds/map/mapNode.js +9 -5
  163. package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
  164. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  165. package/lib/simple-tree/node-kinds/object/objectNode.js +11 -8
  166. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  167. package/lib/simple-tree/schemaTypes.d.ts +13 -27
  168. package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
  169. package/lib/simple-tree/schemaTypes.js +42 -35
  170. package/lib/simple-tree/schemaTypes.js.map +1 -1
  171. package/lib/simple-tree/toStoredSchema.d.ts +2 -0
  172. package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
  173. package/lib/simple-tree/toStoredSchema.js +2 -0
  174. package/lib/simple-tree/toStoredSchema.js.map +1 -1
  175. package/lib/simple-tree/treeNodeValid.d.ts.map +1 -1
  176. package/lib/simple-tree/treeNodeValid.js +1 -2
  177. package/lib/simple-tree/treeNodeValid.js.map +1 -1
  178. package/lib/simple-tree/walkFieldSchema.d.ts.map +1 -1
  179. package/lib/simple-tree/walkFieldSchema.js +1 -1
  180. package/lib/simple-tree/walkFieldSchema.js.map +1 -1
  181. package/package.json +22 -22
  182. package/src/feature-libraries/flex-tree/flexTreeTypes.ts +1 -1
  183. package/src/index.ts +1 -0
  184. package/src/packageVersion.ts +1 -1
  185. package/src/shared-tree/schematizingTreeView.ts +8 -5
  186. package/src/shared-tree/treeAlpha.ts +188 -3
  187. package/src/simple-tree/api/configuration.ts +59 -27
  188. package/src/simple-tree/api/index.ts +3 -3
  189. package/src/simple-tree/api/treeNodeApi.ts +5 -2
  190. package/src/simple-tree/core/context.ts +3 -3
  191. package/src/simple-tree/core/getOrCreateNode.ts +14 -0
  192. package/src/simple-tree/core/index.ts +7 -1
  193. package/src/simple-tree/core/treeNodeKernel.ts +1 -1
  194. package/src/simple-tree/core/treeNodeSchema.ts +113 -1
  195. package/src/simple-tree/core/walkSchema.ts +16 -7
  196. package/src/simple-tree/createContext.ts +1 -1
  197. package/src/simple-tree/getTreeNodeForField.ts +3 -1
  198. package/src/simple-tree/index.ts +9 -5
  199. package/src/simple-tree/leafNodeSchema.ts +7 -1
  200. package/src/simple-tree/node-kinds/array/arrayNode.ts +15 -9
  201. package/src/simple-tree/node-kinds/map/mapNode.ts +10 -4
  202. package/src/simple-tree/node-kinds/object/objectNode.ts +20 -11
  203. package/src/simple-tree/schemaTypes.ts +55 -64
  204. package/src/simple-tree/toStoredSchema.ts +2 -0
  205. package/src/simple-tree/treeNodeValid.ts +1 -1
  206. package/src/simple-tree/walkFieldSchema.ts +5 -1
@@ -372,7 +372,7 @@ export function splitInnerNodeType(
372
372
  ): asserts innerNode is UnhydratedFlexTreeNode | HydratedFlexTreeNode {
373
373
  assert(
374
374
  innerNode instanceof UnhydratedFlexTreeNode || innerNode.isHydrated(),
375
- "Invalid inner node type",
375
+ 0xbc8 /* Invalid inner node type */,
376
376
  );
377
377
  }
378
378
 
@@ -3,7 +3,15 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type { TreeLeafValue } from "../schemaTypes.js";
6
+ import { assert } from "@fluidframework/core-utils/internal";
7
+ import type { LazyItem } from "../flexList.js";
8
+ import type {
9
+ AllowedTypeMetadata,
10
+ AllowedTypesMetadata,
11
+ AnnotatedAllowedTypes,
12
+ ImplicitAnnotatedAllowedTypes,
13
+ TreeLeafValue,
14
+ } from "../schemaTypes.js";
7
15
  import type { SimpleNodeSchemaBase } from "../simpleSchema.js";
8
16
 
9
17
  import type { TreeNode } from "./treeNode.js";
@@ -62,6 +70,48 @@ export type TreeNodeSchema<
62
70
  TCustomMetadata
63
71
  >;
64
72
 
73
+ /**
74
+ * Stores annotations for an individual allowed type.
75
+ * @alpha
76
+ */
77
+ export interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {
78
+ /**
79
+ * Annotations for the allowed type.
80
+ */
81
+ readonly metadata: AllowedTypeMetadata;
82
+ /**
83
+ * The allowed type the annotations apply to in a particular schema.
84
+ */
85
+ readonly type: T;
86
+ }
87
+
88
+ /**
89
+ * Stores annotations for a set of evaluated annotated allowed types.
90
+ * @alpha
91
+ */
92
+ export interface NormalizedAnnotatedAllowedTypes {
93
+ /**
94
+ * Annotations that apply to a set of allowed types.
95
+ */
96
+ readonly metadata: AllowedTypesMetadata;
97
+ /**
98
+ * All the evaluated allowed types that the annotations apply to. The types themselves are also individually annotated.
99
+ */
100
+ readonly types: readonly AnnotatedAllowedType<TreeNodeSchema>[];
101
+ }
102
+
103
+ /**
104
+ * Checks if the input is an {@link AnnotatedAllowedTypes}.
105
+ */
106
+ export function isAnnotatedAllowedTypes(
107
+ allowedTypes: ImplicitAnnotatedAllowedTypes,
108
+ ): allowedTypes is AnnotatedAllowedTypes {
109
+ return (
110
+ // Class based schema, and lazy schema references report type "function": filtering them out with typeof makes narrowing based on members mostly safe
111
+ typeof allowedTypes === "object" && "metadata" in allowedTypes && "types" in allowedTypes
112
+ );
113
+ }
114
+
65
115
  /**
66
116
  * Schema which is not a class.
67
117
  * @remarks
@@ -231,8 +281,13 @@ export type TreeNodeSchemaBoth<
231
281
 
232
282
  /**
233
283
  * Data common to all tree node schema.
284
+ *
234
285
  * @remarks
235
286
  * Implementation detail of {@link TreeNodeSchema} which should be accessed instead of referring to this type directly.
287
+ *
288
+ * @privateRemarks
289
+ * All implementations must implement {@link TreeNodeSchemaCorePrivate} as well.
290
+ *
236
291
  * @sealed @public
237
292
  */
238
293
  export interface TreeNodeSchemaCore<
@@ -316,6 +371,63 @@ export interface TreeNodeSchemaCore<
316
371
  createFromInsertable(data: TInsertable): Unhydrated<TreeNode | TreeLeafValue>;
317
372
  }
318
373
 
374
+ /**
375
+ * {@link TreeNodeSchemaCore} extended with some non-exported APIs.
376
+ */
377
+ export interface TreeNodeSchemaCorePrivate<
378
+ Name extends string = string,
379
+ Kind extends NodeKind = NodeKind,
380
+ TInsertable = never,
381
+ ImplicitlyConstructable extends boolean = boolean,
382
+ Info = unknown,
383
+ TCustomMetadata = unknown,
384
+ > extends TreeNodeSchemaCore<
385
+ Name,
386
+ Kind,
387
+ ImplicitlyConstructable,
388
+ Info,
389
+ TInsertable,
390
+ TCustomMetadata
391
+ > {
392
+ /**
393
+ * All possible annotated allowed types that a field under a node with this schema could have.
394
+ * @remarks
395
+ * In this case "field" includes anything that is a field in the internal (flex-tree) abstraction layer.
396
+ * This includes the content field for arrays, and all the fields for map nodes.
397
+ * If this node does not have fields (and thus is a leaf), the array will be empty.
398
+ *
399
+ * This set cannot be used before the schema in it have been defined:
400
+ * more specifically, when using lazy schema references (for example to make foreword references to schema which have not yet been defined),
401
+ * users must wait until after the schema are defined to access this array.
402
+ *
403
+ * @privateRemarks
404
+ * If this is stabilized, it will live alongside the childTypes property on {@link TreeNodeSchemaCore}.
405
+ * @system
406
+ */
407
+ readonly childAnnotatedAllowedTypes: readonly NormalizedAnnotatedAllowedTypes[];
408
+ }
409
+
410
+ /**
411
+ * Downcasts a {@link TreeNodeSchemaCore} to {@link TreeNodeSchemaCorePrivate} if it is one.
412
+ *
413
+ * @remarks
414
+ * This function should only be used internally. The result should not be exposed publicly
415
+ * in any exported types or API return values.
416
+ */
417
+ export function asTreeNodeSchemaCorePrivate(
418
+ schema: TreeNodeSchemaCore<string, NodeKind, boolean>,
419
+ ): TreeNodeSchemaCorePrivate {
420
+ assert(
421
+ "childAnnotatedAllowedTypes" in schema,
422
+ 0xbc9 /* All implementations of TreeNodeSchemaCore must also implement TreeNodeSchemaCorePrivate */,
423
+ );
424
+ assert(
425
+ Array.isArray((schema as TreeNodeSchemaCorePrivate).childAnnotatedAllowedTypes),
426
+ 0xbca /* All implementations of TreeNodeSchemaCore must also implement TreeNodeSchemaCorePrivate */,
427
+ );
428
+ return schema as TreeNodeSchemaCorePrivate;
429
+ }
430
+
319
431
  /**
320
432
  * Kind of tree node.
321
433
  * @remarks
@@ -3,7 +3,11 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type { TreeNodeSchema } from "./treeNodeSchema.js";
6
+ import {
7
+ asTreeNodeSchemaCorePrivate,
8
+ type NormalizedAnnotatedAllowedTypes,
9
+ type TreeNodeSchema,
10
+ } from "./treeNodeSchema.js";
7
11
 
8
12
  /**
9
13
  * Traverses all {@link TreeNodeSchema} schema reachable from `schema`, applying the visitor pattern.
@@ -16,9 +20,14 @@ export function walkNodeSchema(
16
20
  if (visitedSet.has(schema)) {
17
21
  return;
18
22
  }
23
+
19
24
  visitedSet.add(schema);
20
25
 
21
- walkAllowedTypes(schema.childTypes, visitor, visitedSet);
26
+ const annotatedAllowedTypes = asTreeNodeSchemaCorePrivate(schema).childAnnotatedAllowedTypes;
27
+
28
+ for (const fieldAllowedTypes of annotatedAllowedTypes) {
29
+ walkAllowedTypes(fieldAllowedTypes, visitor, visitedSet);
30
+ }
22
31
 
23
32
  // This visit is done at the end so the traversal order is most inner types first.
24
33
  // This was picked since when fixing errors,
@@ -31,14 +40,14 @@ export function walkNodeSchema(
31
40
  * Traverses all {@link TreeNodeSchema} schema reachable from `allowedTypes`, applying the visitor pattern.
32
41
  */
33
42
  export function walkAllowedTypes(
34
- allowedTypes: Iterable<TreeNodeSchema>,
43
+ annotatedAllowedTypes: NormalizedAnnotatedAllowedTypes,
35
44
  visitor: SchemaVisitor,
36
45
  visitedSet: Set<TreeNodeSchema> = new Set(),
37
46
  ): void {
38
- for (const childType of allowedTypes) {
39
- walkNodeSchema(childType, visitor, visitedSet);
47
+ for (const { type } of annotatedAllowedTypes.types) {
48
+ walkNodeSchema(type, visitor, visitedSet);
40
49
  }
41
- visitor.allowedTypes?.(allowedTypes);
50
+ visitor.allowedTypes?.(annotatedAllowedTypes);
42
51
  }
43
52
 
44
53
  /**
@@ -55,5 +64,5 @@ export interface SchemaVisitor {
55
64
  *
56
65
  * This includes every field, but also the allowed types array for maps and arrays and the root if starting at {@link walkAllowedTypes}.
57
66
  */
58
- allowedTypes?: (allowedTypes: Iterable<TreeNodeSchema>) => void;
67
+ allowedTypes?: (allowedTypes: NormalizedAnnotatedAllowedTypes) => void;
59
68
  }
@@ -20,6 +20,6 @@ export function getUnhydratedContext(schema: ImplicitFieldSchema): Context {
20
20
  const normalized = normalizeFieldSchema(schema);
21
21
 
22
22
  const flexContext = new UnhydratedContext(defaultSchemaPolicy, toStoredSchema(schema));
23
- return new Context(normalized.allowedTypeSet, flexContext);
23
+ return new Context(normalized.annotatedAllowedTypesNormalized, flexContext);
24
24
  });
25
25
  }
@@ -19,7 +19,9 @@ import { type TreeNode, getOrCreateNodeFromInnerNode } from "./core/index.js";
19
19
  /**
20
20
  * Retrieve the associated {@link TreeNode} for the given field's content.
21
21
  */
22
- export function getTreeNodeForField(field: FlexTreeField): TreeNode | TreeValue | undefined {
22
+ export function tryGetTreeNodeForField(
23
+ field: FlexTreeField,
24
+ ): TreeNode | TreeValue | undefined {
23
25
  function tryToUnboxLeaves(
24
26
  flexField: FlexTreeOptionalField | FlexTreeRequiredField,
25
27
  ): TreeNode | TreeValue | undefined {
@@ -8,6 +8,8 @@ export {
8
8
  typeSchemaSymbol,
9
9
  type WithType,
10
10
  type TreeNodeSchema,
11
+ type AnnotatedAllowedType,
12
+ type NormalizedAnnotatedAllowedTypes,
11
13
  NodeKind,
12
14
  type TreeNodeSchemaClass,
13
15
  type TreeNodeSchemaNonClass,
@@ -23,6 +25,7 @@ export {
23
25
  SimpleContextSlot,
24
26
  getOrCreateInnerNode,
25
27
  getOrCreateNodeFromInnerNode,
28
+ getOrCreateNodeFromInnerUnboxedNode,
26
29
  getKernel,
27
30
  } from "./core/index.js";
28
31
  export {
@@ -83,9 +86,9 @@ export {
83
86
  type TreeViewAlpha,
84
87
  type TreeBranch,
85
88
  type TreeBranchEvents,
86
- tryGetSchema,
87
- getStoredKey,
88
89
  getPropertyKeyFromStoredKey,
90
+ getStoredKey,
91
+ tryGetSchema,
89
92
  applySchemaToParserOptions,
90
93
  cursorFromVerbose,
91
94
  verboseFromCursor,
@@ -137,8 +140,6 @@ export type {
137
140
  export {
138
141
  type NodeFromSchema,
139
142
  isTreeNodeSchemaClass,
140
- type AnnotatedAllowedType,
141
- type AnnotatedAllowedTypes,
142
143
  type ImplicitFieldSchema,
143
144
  type ImplicitAnnotatedFieldSchema,
144
145
  type TreeFieldFromImplicitField,
@@ -157,6 +158,7 @@ export {
157
158
  type AllowedTypes,
158
159
  type AllowedTypeMetadata,
159
160
  type AllowedTypesMetadata,
161
+ type AnnotatedAllowedTypes,
160
162
  FieldKind,
161
163
  FieldSchema,
162
164
  type FieldSchemaAlpha,
@@ -185,11 +187,12 @@ export {
185
187
  type NodeSchemaMetadata,
186
188
  evaluateLazySchema,
187
189
  } from "./schemaTypes.js";
188
- export { getTreeNodeForField } from "./getTreeNodeForField.js";
190
+ export { tryGetTreeNodeForField } from "./getTreeNodeForField.js";
189
191
  export {
190
192
  type ArrayNodeCustomizableSchema,
191
193
  type ArrayNodePojoEmulationSchema,
192
194
  ArrayNodeSchema,
195
+ asIndex,
193
196
  isArrayNodeSchema,
194
197
  IterableTreeArrayContent,
195
198
  type ReadonlyArrayNode,
@@ -204,6 +207,7 @@ export {
204
207
  type InsertableObjectFromSchemaRecord,
205
208
  type ObjectFromSchemaRecord,
206
209
  ObjectNodeSchema,
210
+ isObjectNodeSchema,
207
211
  type InsertableObjectFromAnnotatedSchemaRecord,
208
212
  type TreeObjectNode,
209
213
  setField,
@@ -12,7 +12,12 @@ import {
12
12
  valueSchemaAllows,
13
13
  } from "../feature-libraries/index.js";
14
14
 
15
- import { NodeKind, type TreeNodeSchema, type TreeNodeSchemaNonClass } from "./core/index.js";
15
+ import {
16
+ NodeKind,
17
+ type NormalizedAnnotatedAllowedTypes,
18
+ type TreeNodeSchema,
19
+ type TreeNodeSchemaNonClass,
20
+ } from "./core/index.js";
16
21
  import type { NodeSchemaMetadata, TreeLeafValue } from "./schemaTypes.js";
17
22
  import type { SimpleLeafNodeSchema } from "./simpleSchema.js";
18
23
  import type { JsonCompatibleReadOnlyObject } from "../util/index.js";
@@ -34,6 +39,7 @@ export class LeafNodeSchema<Name extends string, const T extends ValueSchema>
34
39
  public readonly info: T;
35
40
  public readonly implicitlyConstructable = true as const;
36
41
  public readonly childTypes: ReadonlySet<TreeNodeSchema> = new Set();
42
+ public readonly childAnnotatedAllowedTypes: readonly NormalizedAnnotatedAllowedTypes[] = [];
37
43
 
38
44
  public create(data: TreeValue<T> | FlexTreeNode): TreeValue<T> {
39
45
  if (isFlexTreeNode(data)) {
@@ -7,14 +7,14 @@ import { Lazy, oob, fail } from "@fluidframework/core-utils/internal";
7
7
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
8
8
 
9
9
  import { EmptyKey } from "../../../core/index.js";
10
- import {
11
- type FlexibleFieldContent,
12
- type FlexTreeNode,
13
- type FlexTreeSequenceField,
14
- isFlexTreeNode,
10
+ import type {
11
+ FlexibleFieldContent,
12
+ FlexTreeNode,
13
+ FlexTreeSequenceField,
15
14
  } from "../../../feature-libraries/index.js";
16
15
  import {
17
16
  normalizeAllowedTypes,
17
+ normalizeAnnotatedAllowedTypes,
18
18
  unannotateImplicitAllowedTypes,
19
19
  type ImplicitAllowedTypes,
20
20
  type ImplicitAnnotatedAllowedTypes,
@@ -41,6 +41,8 @@ import {
41
41
  getKernel,
42
42
  type UnhydratedFlexTreeNode,
43
43
  UnhydratedSequenceField,
44
+ getOrCreateNodeFromInnerUnboxedNode,
45
+ type NormalizedAnnotatedAllowedTypes,
44
46
  } from "../../core/index.js";
45
47
  import {
46
48
  type InsertableContent,
@@ -735,9 +737,9 @@ function createArrayNodeProxy(
735
737
  }
736
738
 
737
739
  const maybeContent = field.at(maybeIndex);
738
- return isFlexTreeNode(maybeContent)
739
- ? getOrCreateNodeFromInnerNode(maybeContent)
740
- : maybeContent;
740
+ return maybeContent === undefined
741
+ ? undefined
742
+ : getOrCreateNodeFromInnerUnboxedNode(maybeContent);
741
743
  },
742
744
  set: (target, key, newValue, receiver) => {
743
745
  if (key === "length") {
@@ -796,7 +798,7 @@ function createArrayNodeProxy(
796
798
  // To satisfy 'deepEquals' level scrutiny, the property descriptor for indexed properties must
797
799
  // be a simple value property (as opposed to using getter) and declared writable/enumerable/configurable.
798
800
  return {
799
- value: isFlexTreeNode(val) ? getOrCreateNodeFromInnerNode(val) : val,
801
+ value: val === undefined ? undefined : getOrCreateNodeFromInnerUnboxedNode(val),
800
802
  writable: true, // For MVP, setting indexed properties is reported as allowed here (for deep equals compatibility noted above), but not actually supported.
801
803
  enumerable: true,
802
804
  configurable: true,
@@ -1110,6 +1112,7 @@ export function arraySchema<
1110
1112
  const unannotatedTypes = unannotateImplicitAllowedTypes(info);
1111
1113
 
1112
1114
  const lazyChildTypes = new Lazy(() => normalizeAllowedTypes(unannotatedTypes));
1115
+ const lazyAnnotatedTypes = new Lazy(() => [normalizeAnnotatedAllowedTypes(info)]);
1113
1116
  const lazyAllowedTypesIdentifiers = new Lazy(
1114
1117
  () => new Set([...lazyChildTypes.value].map((type) => type.identifier)),
1115
1118
  );
@@ -1192,6 +1195,9 @@ export function arraySchema<
1192
1195
  public static get childTypes(): ReadonlySet<TreeNodeSchema> {
1193
1196
  return lazyChildTypes.value;
1194
1197
  }
1198
+ public static get childAnnotatedAllowedTypes(): readonly NormalizedAnnotatedAllowedTypes[] {
1199
+ return lazyAnnotatedTypes.value;
1200
+ }
1195
1201
  public static readonly metadata: NodeSchemaMetadata<TCustomMetadata> = metadata ?? {};
1196
1202
  public static readonly persistedMetadata: JsonCompatibleReadOnlyObject | undefined =
1197
1203
  persistedMetadata;
@@ -10,11 +10,12 @@ import type {
10
10
  FlexTreeOptionalField,
11
11
  OptionalFieldEditBuilder,
12
12
  } from "../../../feature-libraries/index.js";
13
- import { getTreeNodeForField } from "../../getTreeNodeForField.js";
13
+ import { tryGetTreeNodeForField } from "../../getTreeNodeForField.js";
14
14
  import {
15
15
  createFieldSchema,
16
16
  FieldKind,
17
17
  normalizeAllowedTypes,
18
+ normalizeAnnotatedAllowedTypes,
18
19
  unannotateImplicitAllowedTypes,
19
20
  type ImplicitAllowedTypes,
20
21
  type ImplicitAnnotatedAllowedTypes,
@@ -36,6 +37,7 @@ import {
36
37
  getOrCreateInnerNode,
37
38
  type InternalTreeNode,
38
39
  type UnhydratedFlexTreeNode,
40
+ type NormalizedAnnotatedAllowedTypes,
39
41
  } from "../../core/index.js";
40
42
  import {
41
43
  unhydratedFlexTreeFromInsertable,
@@ -177,14 +179,14 @@ abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends T
177
179
  for (const key of node.keys()) {
178
180
  yield [
179
181
  key,
180
- getTreeNodeForField(node.getBoxed(key)) as TreeNodeFromImplicitAllowedTypes<T>,
182
+ tryGetTreeNodeForField(node.getBoxed(key)) as TreeNodeFromImplicitAllowedTypes<T>,
181
183
  ];
182
184
  }
183
185
  }
184
186
  public get(key: string): TreeNodeFromImplicitAllowedTypes<T> {
185
187
  const node = this.innerNode;
186
188
  const field = node.getBoxed(brand(key));
187
- return getTreeNodeForField(field) as TreeNodeFromImplicitAllowedTypes<T>;
189
+ return tryGetTreeNodeForField(field) as TreeNodeFromImplicitAllowedTypes<T>;
188
190
  }
189
191
  public has(key: string): boolean {
190
192
  return this.innerNode.tryGetField(brand(key)) !== undefined;
@@ -221,7 +223,7 @@ abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends T
221
223
  thisArg?: unknown,
222
224
  ): void {
223
225
  for (const field of getOrCreateInnerNode(this)) {
224
- const node = getTreeNodeForField(field) as TreeNodeFromImplicitAllowedTypes<T>;
226
+ const node = tryGetTreeNodeForField(field) as TreeNodeFromImplicitAllowedTypes<T>;
225
227
  callbackFn.call(thisArg, node, field.key, this);
226
228
  }
227
229
  }
@@ -252,6 +254,7 @@ export function mapSchema<
252
254
  const lazyChildTypes = new Lazy(() =>
253
255
  normalizeAllowedTypes(unannotateImplicitAllowedTypes(info)),
254
256
  );
257
+ const lazyAnnotatedTypes = new Lazy(() => [normalizeAnnotatedAllowedTypes(info)]);
255
258
  const lazyAllowedTypesIdentifiers = new Lazy(
256
259
  () => new Set([...lazyChildTypes.value].map((type) => type.identifier)),
257
260
  );
@@ -300,6 +303,9 @@ export function mapSchema<
300
303
  public static get childTypes(): ReadonlySet<TreeNodeSchema> {
301
304
  return lazyChildTypes.value;
302
305
  }
306
+ public static get childAnnotatedAllowedTypes(): readonly NormalizedAnnotatedAllowedTypes[] {
307
+ return lazyAnnotatedTypes.value;
308
+ }
303
309
  public static readonly metadata: NodeSchemaMetadata<TCustomMetadata> = metadata ?? {};
304
310
  public static readonly persistedMetadata: JsonCompatibleReadOnlyObject | undefined =
305
311
  persistedMetadata;
@@ -32,9 +32,10 @@ import {
32
32
  type Context,
33
33
  type UnhydratedFlexTreeNode,
34
34
  getOrCreateInnerNode,
35
+ type NormalizedAnnotatedAllowedTypes,
35
36
  } from "../../core/index.js";
36
37
  import { getUnhydratedContext } from "../../createContext.js";
37
- import { getTreeNodeForField } from "../../getTreeNodeForField.js";
38
+ import { tryGetTreeNodeForField } from "../../getTreeNodeForField.js";
38
39
  import {
39
40
  isObjectNodeSchema,
40
41
  type ObjectNodeSchema,
@@ -54,7 +55,6 @@ import {
54
55
  type FieldSchemaAlpha,
55
56
  ObjectFieldSchema,
56
57
  type ImplicitAnnotatedFieldSchema,
57
- unannotateSchemaRecord,
58
58
  type UnannotateSchemaRecord,
59
59
  } from "../../schemaTypes.js";
60
60
  import type { SimpleObjectFieldSchema } from "../../simpleSchema.js";
@@ -194,7 +194,9 @@ export type SimpleKeyMap = ReadonlyMap<
194
194
  /**
195
195
  * Caches the mappings from property keys to stored keys for the provided object field schemas in {@link simpleKeyToFlexKeyCache}.
196
196
  */
197
- function createFlexKeyMapping(fields: Record<string, ImplicitFieldSchema>): SimpleKeyMap {
197
+ function createFlexKeyMapping(
198
+ fields: Record<string, ImplicitAnnotatedFieldSchema>,
199
+ ): SimpleKeyMap {
198
200
  const keyMap: Map<string | symbol, { storedKey: FieldKey; schema: FieldSchema }> = new Map();
199
201
  for (const [propertyKey, fieldSchema] of Object.entries(fields)) {
200
202
  const storedKey = getStoredKey(propertyKey, fieldSchema);
@@ -234,13 +236,13 @@ function createProxyHandler(
234
236
  debugAssert(() => !flexNode.context.isDisposed() || "FlexTreeNode is disposed");
235
237
  const field = flexNode.tryGetField(fieldInfo.storedKey);
236
238
  if (field !== undefined) {
237
- return getTreeNodeForField(field);
239
+ return tryGetTreeNodeForField(field);
238
240
  }
239
241
 
240
242
  return undefined;
241
243
  }
242
244
 
243
- // POJO mode objects don't have TreeNode's build in members on their targets, so special case them:
245
+ // POJO mode objects don't have TreeNode's built in members on their targets, so special case them:
244
246
  if (propertyKey === typeSchemaSymbol) {
245
247
  return schema;
246
248
  }
@@ -302,7 +304,7 @@ function createProxyHandler(
302
304
  const field = getOrCreateInnerNode(proxy).tryGetField(fieldInfo.storedKey);
303
305
 
304
306
  const p: PropertyDescriptor = {
305
- value: field === undefined ? undefined : getTreeNodeForField(field),
307
+ value: field === undefined ? undefined : tryGetTreeNodeForField(field),
306
308
  writable: true,
307
309
  // Report empty fields as own properties so they shadow inherited properties (even when empty) to match TypeScript typing.
308
310
  // Make empty fields not enumerable so they get skipped when iterating over an object to better align with
@@ -372,14 +374,12 @@ export function objectSchema<
372
374
  // Field set can't be modified after this since derived data is stored in maps.
373
375
  Object.freeze(info);
374
376
 
375
- const unannotatedInfo = unannotateSchemaRecord(info);
376
-
377
377
  // Ensure no collisions between final set of property keys, and final set of stored keys (including those
378
378
  // implicitly derived from property keys)
379
- assertUniqueKeys(identifier, unannotatedInfo);
379
+ assertUniqueKeys(identifier, info);
380
380
 
381
381
  // Performance optimization: cache property key => stored key and schema.
382
- const flexKeyMap: SimpleKeyMap = createFlexKeyMapping(unannotatedInfo);
382
+ const flexKeyMap: SimpleKeyMap = createFlexKeyMapping(info);
383
383
 
384
384
  const identifierFieldKeys: FieldKey[] = [];
385
385
  for (const item of flexKeyMap.values()) {
@@ -391,6 +391,12 @@ export function objectSchema<
391
391
  const lazyChildTypes = new Lazy(
392
392
  () => new Set(Array.from(flexKeyMap.values(), (f) => [...f.schema.allowedTypeSet]).flat()),
393
393
  );
394
+ const lazyAnnotatedTypes = new Lazy(() =>
395
+ Array.from(
396
+ flexKeyMap.values(),
397
+ ({ schema }) => normalizeFieldSchema(schema).annotatedAllowedTypesNormalized,
398
+ ),
399
+ );
394
400
 
395
401
  let handler: ProxyHandler<object>;
396
402
  let customizable: boolean;
@@ -509,6 +515,9 @@ export function objectSchema<
509
515
  public static get childTypes(): ReadonlySet<TreeNodeSchema> {
510
516
  return lazyChildTypes.value;
511
517
  }
518
+ public static get childAnnotatedAllowedTypes(): readonly NormalizedAnnotatedAllowedTypes[] {
519
+ return lazyAnnotatedTypes.value;
520
+ }
512
521
  public static readonly metadata: NodeSchemaMetadata<TCustomMetadata> = metadata ?? {};
513
522
  public static readonly persistedMetadata: JsonCompatibleReadOnlyObject | undefined =
514
523
  persistedMetadata;
@@ -537,7 +546,7 @@ const targetToProxy: WeakMap<object, TreeNode> = new WeakMap();
537
546
  */
538
547
  function assertUniqueKeys<
539
548
  const Name extends number | string,
540
- const Fields extends RestrictiveStringRecord<ImplicitFieldSchema>,
549
+ const Fields extends RestrictiveStringRecord<ImplicitAnnotatedFieldSchema>,
541
550
  >(schemaName: Name, fields: Fields): void {
542
551
  // Verify that there are no duplicates among the explicitly specified stored keys.
543
552
  const explicitStoredKeys = new Set<string>();