@fluidframework/tree 2.31.1 → 2.32.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 (242) hide show
  1. package/.vscode/settings.json +1 -1
  2. package/CHANGELOG.md +44 -0
  3. package/api-extractor/api-extractor.current.json +5 -1
  4. package/api-report/tree.alpha.api.md +44 -20
  5. package/dist/alpha.d.ts +6 -2
  6. package/dist/feature-libraries/flex-tree/context.d.ts +1 -1
  7. package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
  8. package/dist/feature-libraries/flex-tree/context.js +1 -2
  9. package/dist/feature-libraries/flex-tree/context.js.map +1 -1
  10. package/dist/feature-libraries/flex-tree/index.d.ts +1 -1
  11. package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
  12. package/dist/feature-libraries/flex-tree/index.js +1 -2
  13. package/dist/feature-libraries/flex-tree/index.js.map +1 -1
  14. package/dist/feature-libraries/flex-tree/lazyEntity.d.ts +6 -15
  15. package/dist/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
  16. package/dist/feature-libraries/flex-tree/lazyEntity.js +9 -18
  17. package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  18. package/dist/feature-libraries/flex-tree/lazyField.d.ts +3 -3
  19. package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  20. package/dist/feature-libraries/flex-tree/lazyField.js +14 -14
  21. package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
  22. package/dist/feature-libraries/flex-tree/lazyNode.d.ts +4 -4
  23. package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  24. package/dist/feature-libraries/flex-tree/lazyNode.js +12 -12
  25. package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  26. package/dist/feature-libraries/index.d.ts +1 -1
  27. package/dist/feature-libraries/index.d.ts.map +1 -1
  28. package/dist/feature-libraries/index.js +1 -2
  29. package/dist/feature-libraries/index.js.map +1 -1
  30. package/dist/index.d.ts +2 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +5 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/packageVersion.d.ts +1 -1
  35. package/dist/packageVersion.js +1 -1
  36. package/dist/packageVersion.js.map +1 -1
  37. package/dist/shared-tree/sharedTree.js +2 -2
  38. package/dist/shared-tree/sharedTree.js.map +1 -1
  39. package/dist/shared-tree/treeApiAlpha.d.ts +6 -6
  40. package/dist/shared-tree/treeApiAlpha.d.ts.map +1 -1
  41. package/dist/shared-tree/treeApiAlpha.js.map +1 -1
  42. package/dist/shared-tree-core/sharedTreeCore.d.ts +0 -6
  43. package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  44. package/dist/shared-tree-core/sharedTreeCore.js +0 -17
  45. package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
  46. package/dist/simple-tree/api/conciseTree.d.ts +2 -2
  47. package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
  48. package/dist/simple-tree/api/conciseTree.js.map +1 -1
  49. package/dist/simple-tree/api/customTree.d.ts +14 -12
  50. package/dist/simple-tree/api/customTree.d.ts.map +1 -1
  51. package/dist/simple-tree/api/customTree.js.map +1 -1
  52. package/dist/simple-tree/api/getJsonSchema.d.ts +21 -7
  53. package/dist/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  54. package/dist/simple-tree/api/getJsonSchema.js +8 -16
  55. package/dist/simple-tree/api/getJsonSchema.js.map +1 -1
  56. package/dist/simple-tree/api/getSimpleSchema.d.ts +3 -10
  57. package/dist/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
  58. package/dist/simple-tree/api/getSimpleSchema.js +4 -16
  59. package/dist/simple-tree/api/getSimpleSchema.js.map +1 -1
  60. package/dist/simple-tree/api/index.d.ts +4 -3
  61. package/dist/simple-tree/api/index.d.ts.map +1 -1
  62. package/dist/simple-tree/api/index.js +2 -1
  63. package/dist/simple-tree/api/index.js.map +1 -1
  64. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
  65. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  66. package/dist/simple-tree/api/schemaFactoryAlpha.js +4 -0
  67. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  68. package/dist/simple-tree/api/schemaFromSimple.d.ts +5 -2
  69. package/dist/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
  70. package/dist/simple-tree/api/schemaFromSimple.js +24 -8
  71. package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
  72. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +11 -3
  73. package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  74. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +40 -28
  75. package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  76. package/dist/simple-tree/api/tree.d.ts +32 -5
  77. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  78. package/dist/simple-tree/api/tree.js +17 -1
  79. package/dist/simple-tree/api/tree.js.map +1 -1
  80. package/dist/simple-tree/api/verboseTree.d.ts +4 -28
  81. package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
  82. package/dist/simple-tree/api/verboseTree.js.map +1 -1
  83. package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
  84. package/dist/simple-tree/api/viewSchemaToSimpleSchema.js +7 -3
  85. package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
  86. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  87. package/dist/simple-tree/core/treeNodeKernel.js +7 -6
  88. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  89. package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  90. package/dist/simple-tree/core/unhydratedFlexTree.js +12 -1
  91. package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  92. package/dist/simple-tree/index.d.ts +1 -1
  93. package/dist/simple-tree/index.d.ts.map +1 -1
  94. package/dist/simple-tree/index.js +3 -2
  95. package/dist/simple-tree/index.js.map +1 -1
  96. package/dist/simple-tree/simpleSchema.d.ts +4 -11
  97. package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
  98. package/dist/simple-tree/simpleSchema.js.map +1 -1
  99. package/dist/tableSchema.d.ts +227 -0
  100. package/dist/tableSchema.d.ts.map +1 -0
  101. package/dist/tableSchema.js +234 -0
  102. package/dist/tableSchema.js.map +1 -0
  103. package/dist/treeFactory.d.ts +4 -4
  104. package/dist/treeFactory.d.ts.map +1 -1
  105. package/dist/treeFactory.js.map +1 -1
  106. package/dist/util/breakable.d.ts.map +1 -1
  107. package/dist/util/breakable.js +9 -7
  108. package/dist/util/breakable.js.map +1 -1
  109. package/lib/alpha.d.ts +6 -2
  110. package/lib/feature-libraries/flex-tree/context.d.ts +1 -1
  111. package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
  112. package/lib/feature-libraries/flex-tree/context.js +1 -2
  113. package/lib/feature-libraries/flex-tree/context.js.map +1 -1
  114. package/lib/feature-libraries/flex-tree/index.d.ts +1 -1
  115. package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
  116. package/lib/feature-libraries/flex-tree/index.js +1 -1
  117. package/lib/feature-libraries/flex-tree/index.js.map +1 -1
  118. package/lib/feature-libraries/flex-tree/lazyEntity.d.ts +6 -15
  119. package/lib/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
  120. package/lib/feature-libraries/flex-tree/lazyEntity.js +8 -17
  121. package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
  122. package/lib/feature-libraries/flex-tree/lazyField.d.ts +3 -3
  123. package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
  124. package/lib/feature-libraries/flex-tree/lazyField.js +15 -15
  125. package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
  126. package/lib/feature-libraries/flex-tree/lazyNode.d.ts +4 -4
  127. package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
  128. package/lib/feature-libraries/flex-tree/lazyNode.js +13 -13
  129. package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
  130. package/lib/feature-libraries/index.d.ts +1 -1
  131. package/lib/feature-libraries/index.d.ts.map +1 -1
  132. package/lib/feature-libraries/index.js +1 -1
  133. package/lib/feature-libraries/index.js.map +1 -1
  134. package/lib/index.d.ts +2 -1
  135. package/lib/index.d.ts.map +1 -1
  136. package/lib/index.js +2 -1
  137. package/lib/index.js.map +1 -1
  138. package/lib/packageVersion.d.ts +1 -1
  139. package/lib/packageVersion.js +1 -1
  140. package/lib/packageVersion.js.map +1 -1
  141. package/lib/shared-tree/sharedTree.js +2 -2
  142. package/lib/shared-tree/sharedTree.js.map +1 -1
  143. package/lib/shared-tree/treeApiAlpha.d.ts +6 -6
  144. package/lib/shared-tree/treeApiAlpha.d.ts.map +1 -1
  145. package/lib/shared-tree/treeApiAlpha.js.map +1 -1
  146. package/lib/shared-tree-core/sharedTreeCore.d.ts +0 -6
  147. package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
  148. package/lib/shared-tree-core/sharedTreeCore.js +0 -17
  149. package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
  150. package/lib/simple-tree/api/conciseTree.d.ts +2 -2
  151. package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
  152. package/lib/simple-tree/api/conciseTree.js.map +1 -1
  153. package/lib/simple-tree/api/customTree.d.ts +14 -12
  154. package/lib/simple-tree/api/customTree.d.ts.map +1 -1
  155. package/lib/simple-tree/api/customTree.js.map +1 -1
  156. package/lib/simple-tree/api/getJsonSchema.d.ts +21 -7
  157. package/lib/simple-tree/api/getJsonSchema.d.ts.map +1 -1
  158. package/lib/simple-tree/api/getJsonSchema.js +8 -16
  159. package/lib/simple-tree/api/getJsonSchema.js.map +1 -1
  160. package/lib/simple-tree/api/getSimpleSchema.d.ts +3 -10
  161. package/lib/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
  162. package/lib/simple-tree/api/getSimpleSchema.js +4 -16
  163. package/lib/simple-tree/api/getSimpleSchema.js.map +1 -1
  164. package/lib/simple-tree/api/index.d.ts +4 -3
  165. package/lib/simple-tree/api/index.d.ts.map +1 -1
  166. package/lib/simple-tree/api/index.js +1 -1
  167. package/lib/simple-tree/api/index.js.map +1 -1
  168. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
  169. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  170. package/lib/simple-tree/api/schemaFactoryAlpha.js +4 -0
  171. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  172. package/lib/simple-tree/api/schemaFromSimple.d.ts +5 -2
  173. package/lib/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
  174. package/lib/simple-tree/api/schemaFromSimple.js +24 -8
  175. package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
  176. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +11 -3
  177. package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
  178. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +41 -29
  179. package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
  180. package/lib/simple-tree/api/tree.d.ts +32 -5
  181. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  182. package/lib/simple-tree/api/tree.js +16 -1
  183. package/lib/simple-tree/api/tree.js.map +1 -1
  184. package/lib/simple-tree/api/verboseTree.d.ts +4 -28
  185. package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
  186. package/lib/simple-tree/api/verboseTree.js.map +1 -1
  187. package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
  188. package/lib/simple-tree/api/viewSchemaToSimpleSchema.js +7 -3
  189. package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
  190. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  191. package/lib/simple-tree/core/treeNodeKernel.js +8 -7
  192. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  193. package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
  194. package/lib/simple-tree/core/unhydratedFlexTree.js +12 -1
  195. package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
  196. package/lib/simple-tree/index.d.ts +1 -1
  197. package/lib/simple-tree/index.d.ts.map +1 -1
  198. package/lib/simple-tree/index.js +1 -1
  199. package/lib/simple-tree/index.js.map +1 -1
  200. package/lib/simple-tree/simpleSchema.d.ts +4 -11
  201. package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
  202. package/lib/simple-tree/simpleSchema.js.map +1 -1
  203. package/lib/tableSchema.d.ts +227 -0
  204. package/lib/tableSchema.d.ts.map +1 -0
  205. package/lib/tableSchema.js +231 -0
  206. package/lib/tableSchema.js.map +1 -0
  207. package/lib/treeFactory.d.ts +4 -4
  208. package/lib/treeFactory.d.ts.map +1 -1
  209. package/lib/treeFactory.js.map +1 -1
  210. package/lib/util/breakable.d.ts.map +1 -1
  211. package/lib/util/breakable.js +9 -7
  212. package/lib/util/breakable.js.map +1 -1
  213. package/package.json +23 -22
  214. package/src/feature-libraries/flex-tree/context.ts +2 -2
  215. package/src/feature-libraries/flex-tree/index.ts +0 -1
  216. package/src/feature-libraries/flex-tree/lazyEntity.ts +11 -21
  217. package/src/feature-libraries/flex-tree/lazyField.ts +17 -26
  218. package/src/feature-libraries/flex-tree/lazyNode.ts +13 -19
  219. package/src/feature-libraries/index.ts +0 -1
  220. package/src/index.ts +6 -2
  221. package/src/packageVersion.ts +1 -1
  222. package/src/shared-tree/sharedTree.ts +2 -2
  223. package/src/shared-tree/treeApiAlpha.ts +17 -15
  224. package/src/shared-tree-core/sharedTreeCore.ts +0 -23
  225. package/src/simple-tree/api/conciseTree.ts +4 -4
  226. package/src/simple-tree/api/customTree.ts +16 -14
  227. package/src/simple-tree/api/getJsonSchema.ts +25 -16
  228. package/src/simple-tree/api/getSimpleSchema.ts +4 -18
  229. package/src/simple-tree/api/index.ts +4 -2
  230. package/src/simple-tree/api/schemaFactoryAlpha.ts +18 -1
  231. package/src/simple-tree/api/schemaFromSimple.ts +45 -16
  232. package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +53 -34
  233. package/src/simple-tree/api/tree.ts +51 -4
  234. package/src/simple-tree/api/verboseTree.ts +7 -32
  235. package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +8 -3
  236. package/src/simple-tree/core/treeNodeKernel.ts +11 -7
  237. package/src/simple-tree/core/unhydratedFlexTree.ts +17 -4
  238. package/src/simple-tree/index.ts +4 -2
  239. package/src/simple-tree/simpleSchema.ts +4 -12
  240. package/src/tableSchema.ts +609 -0
  241. package/src/treeFactory.ts +4 -3
  242. package/src/util/breakable.ts +9 -6
@@ -6,7 +6,6 @@
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
7
  import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
8
8
  import type { IIdCompressor, SessionId } from "@fluidframework/id-compressor";
9
- import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
10
9
  import type {
11
10
  IExperimentalIncrementalSummaryContext,
12
11
  IRuntimeMessageCollection,
@@ -331,28 +330,6 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange>
331
330
  this.resubmitMachine.onCommitSubmitted(enrichedCommit);
332
331
  }
333
332
 
334
- /**
335
- * Process a message from the runtime.
336
- * @deprecated - Use processMessagesCore to process a bunch of messages together.
337
- */
338
- public processCore(
339
- message: ISequencedDocumentMessage,
340
- local: boolean,
341
- localOpMetadata: unknown,
342
- ): void {
343
- this.processMessagesCore({
344
- envelope: message,
345
- local,
346
- messagesContent: [
347
- {
348
- clientSequenceNumber: message.clientSequenceNumber,
349
- contents: message.contents,
350
- localOpMetadata,
351
- },
352
- ],
353
- });
354
- }
355
-
356
333
  /**
357
334
  * Process a bunch of messages from the runtime. SharedObject will call this method with a bunch of messages.
358
335
  */
@@ -11,7 +11,7 @@ import type { TreeNodeSchema } from "../core/index.js";
11
11
  import {
12
12
  customFromCursor,
13
13
  replaceHandles,
14
- type EncodeOptions,
14
+ type TreeEncodingOptions,
15
15
  type HandleConverter,
16
16
  } from "./customTree.js";
17
17
  import { getUnhydratedContext } from "../createContext.js";
@@ -44,9 +44,9 @@ export type ConciseTree<THandle = IFluidHandle> =
44
44
  export function conciseFromCursor(
45
45
  reader: ITreeCursor,
46
46
  rootSchema: ImplicitAllowedTypes,
47
- options: EncodeOptions,
47
+ options: TreeEncodingOptions,
48
48
  ): ConciseTree {
49
- const config: Required<EncodeOptions> = {
49
+ const config: Required<TreeEncodingOptions> = {
50
50
  useStoredKeys: false,
51
51
  ...options,
52
52
  };
@@ -57,7 +57,7 @@ export function conciseFromCursor(
57
57
 
58
58
  function conciseFromCursorInner(
59
59
  reader: ITreeCursor,
60
- options: Required<EncodeOptions>,
60
+ options: Required<TreeEncodingOptions>,
61
61
  schema: ReadonlyMap<string, TreeNodeSchema>,
62
62
  ): ConciseTree {
63
63
  return customFromCursor(reader, options, schema, conciseFromCursorInner);
@@ -33,26 +33,20 @@ import { isObjectNodeSchema } from "../objectNodeTypes.js";
33
33
  import { FieldKinds, valueSchemaAllows } from "../../feature-libraries/index.js";
34
34
 
35
35
  /**
36
- * Options for how to encode a tree.
36
+ * Options for how to interpret or encode a tree when schema information is available.
37
37
  * @alpha
38
38
  */
39
- export interface EncodeOptions {
39
+ export interface TreeEncodingOptions {
40
40
  /**
41
- * If true, interpret the input keys of object nodes as stored keys.
42
- * If false, interpret them as property keys.
41
+ * If true, use the stored keys of object nodes.
42
+ * If false, use the property keys.
43
+ * @remarks
44
+ * Has no effect on {@link NodeKind}s other than {@link NodeKind.Object}.
43
45
  * @defaultValue false.
44
46
  */
45
47
  readonly useStoredKeys?: boolean;
46
48
  }
47
49
 
48
- /**
49
- * Options for how to transcode handles.
50
- * @remarks
51
- * Can be applied using {@link replaceHandles}.
52
- * @alpha
53
- */
54
- export type HandleConverter<TCustom> = (data: IFluidHandle) => TCustom;
55
-
56
50
  /**
57
51
  * Options for how to interpret a `ConciseTree<TCustom>` without relying on schema.
58
52
  */
@@ -86,11 +80,11 @@ export type CustomTreeNode<TChild> = TChild[] | { [key: string]: TChild };
86
80
  */
87
81
  export function customFromCursor<TChild>(
88
82
  reader: ITreeCursor,
89
- options: Required<EncodeOptions>,
83
+ options: Required<TreeEncodingOptions>,
90
84
  schema: ReadonlyMap<string, TreeNodeSchema>,
91
85
  childHandler: (
92
86
  reader: ITreeCursor,
93
- options: Required<EncodeOptions>,
87
+ options: Required<TreeEncodingOptions>,
94
88
  schema: ReadonlyMap<string, TreeNodeSchema>,
95
89
  ) => TChild,
96
90
  ): CustomTree<TChild> {
@@ -203,6 +197,14 @@ export function tryStoredSchemaAsArray(
203
197
  }
204
198
  }
205
199
 
200
+ /**
201
+ * Options for how to transcode handles.
202
+ * @remarks
203
+ * Can be applied using {@link replaceHandles}.
204
+ * @alpha
205
+ */
206
+ export type HandleConverter<TCustom> = (data: IFluidHandle) => TCustom;
207
+
206
208
  /**
207
209
  * Clones tree, replacing any handles.
208
210
  * @remarks
@@ -4,16 +4,25 @@
4
4
  */
5
5
 
6
6
  import type { JsonTreeSchema } from "./jsonSchema.js";
7
- import type { ImplicitFieldSchema } from "../schemaTypes.js";
7
+ import type { ImplicitAllowedTypes } from "../schemaTypes.js";
8
8
  import { toJsonSchema } from "./simpleSchemaToJsonSchema.js";
9
- import { getSimpleSchema } from "./getSimpleSchema.js";
10
- import { getOrCreate } from "../../util/index.js";
11
- import type { TreeNodeSchema } from "../core/index.js";
9
+ import type { TreeEncodingOptions } from "./customTree.js";
10
+ import { TreeViewConfigurationAlpha } from "./tree.js";
12
11
 
13
12
  /**
14
- * Cache in which the results of {@link getJsonSchema} are saved.
13
+ * Options for how to interpret or encode a tree when schema information is available.
14
+ * @alpha
15
15
  */
16
- const jsonSchemaCache = new WeakMap<TreeNodeSchema, JsonTreeSchema>();
16
+ export interface TreeSchemaEncodingOptions extends TreeEncodingOptions {
17
+ /**
18
+ * If true, fields with default providers (like {@link SchemaFactory.identifier}) will be required.
19
+ * If false, they will be optional.
20
+ * @remarks
21
+ * Has no effect on {@link NodeKind}s other than {@link NodeKind.Object}.
22
+ * @defaultValue false.
23
+ */
24
+ readonly requireFieldsWithDefaults?: boolean;
25
+ }
17
26
 
18
27
  /**
19
28
  * Creates a {@link https://json-schema.org/ | JSON Schema} representation of the provided {@link TreeNodeSchema}.
@@ -63,18 +72,18 @@ const jsonSchemaCache = new WeakMap<TreeNodeSchema, JsonTreeSchema>();
63
72
  * TODO:
64
73
  * This API should allow generating JSON schema for the whole matrix of combinations:
65
74
  *
66
- * 1. VerboseTree and ConciseTree
67
- * 2. With and without requiring values with defaults (for insertion vs reading)
68
- * 3. Using stored keys and property keys
69
- *
70
- * This current API seems to give ConciseTree with property keys and ignoring default values.
75
+ * 1. VerboseTree and (Done) ConciseTree
76
+ * 2. (Done) With and without requiring values with defaults (for insertion vs reading)
77
+ * 3. (Done) Using stored keys and property keys.
71
78
  *
79
+ * This takes in `ImplicitAllowedTypes` since underlying `toJsonSchema` can't handle optional roots.
72
80
  *
73
81
  * @alpha
74
82
  */
75
- export function getJsonSchema(schema: ImplicitFieldSchema): JsonTreeSchema {
76
- return getOrCreate(jsonSchemaCache, schema, () => {
77
- const simpleSchema = getSimpleSchema(schema);
78
- return toJsonSchema(simpleSchema);
79
- });
83
+ export function getJsonSchema(
84
+ schema: ImplicitAllowedTypes,
85
+ options: Required<TreeSchemaEncodingOptions>,
86
+ ): JsonTreeSchema {
87
+ const treeSchema = new TreeViewConfigurationAlpha({ schema });
88
+ return toJsonSchema(treeSchema, options);
80
89
  }
@@ -3,39 +3,25 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { getOrCreate } from "../../util/index.js";
7
- import type { TreeNodeSchema } from "../core/index.js";
8
6
  import type { ImplicitFieldSchema } from "../schemaTypes.js";
9
7
  import type { SimpleTreeSchema } from "../simpleSchema.js";
10
8
  import { toSimpleTreeSchema } from "./viewSchemaToSimpleSchema.js";
11
9
 
12
10
  /**
13
- * Cache in which the results of {@link getSimpleSchema} saved.
14
- */
15
- const simpleSchemaCache = new WeakMap<TreeNodeSchema, SimpleTreeSchema>();
16
-
17
- /**
18
- * Creates a {@link SimpleTreeSchema} from the provided {@link ImplicitFieldSchema}.
11
+ * Copies data from {@link ImplicitFieldSchema} to create a {@link SimpleTreeSchema} out of new plain JavaScript objects, Sets and Maps.
19
12
  *
20
13
  * @remarks
21
- * This provides easy access by identifier to any schema transitively referenced by the input schema via {@link SimpleTreeSchema.definitions}.
22
- *
23
- * Caches the result on the input schema for future calls.
14
+ * See also {@link TreeViewConfigurationAlpha} which implements {@link SimpleTreeSchema} as a way to get a `SimpleTreeSchema` without copying the node and field schema and without losing as much type information.
24
15
  *
25
16
  * @privateRemarks
26
17
  * In the future, we may wish to move this to a more discoverable API location.
27
18
  * For now, while still an experimental API, it is surfaced as a free function.
28
19
  *
29
- * If the main use for this is the "definitions" map, we should provide a better way to access it (that doesn't type erase the TreeNodeSchema down to SimpleNodeSchema).
30
- * TODO: Having TreeViewConfiguration implement SimpleTreeSchema directly but with more specific types would be a good way to do this.
31
- *
32
20
  * Note that all TreeNodeSchema get a {@link Context} cached on them as part of one time initialization which contains a map from identifier to all transitively referenced schema.
33
21
  * Perhaps exposing access to that would cover this use-case as well.
34
22
  *
35
- * TODO: does having this caching layer add value? Maybe this wrapper around toSimpleTreeSchema should be removed.
36
- *
37
- * @internal
23
+ * @alpha
38
24
  */
39
25
  export function getSimpleSchema(schema: ImplicitFieldSchema): SimpleTreeSchema {
40
- return getOrCreate(simpleSchemaCache, schema, () => toSimpleTreeSchema(schema, false));
26
+ return toSimpleTreeSchema(schema, true);
41
27
  }
@@ -9,6 +9,8 @@ export {
9
9
  type ViewableTree,
10
10
  type TreeViewEvents,
11
11
  TreeViewConfiguration,
12
+ TreeViewConfigurationAlpha,
13
+ type TreeSchema,
12
14
  type ITreeViewConfiguration,
13
15
  type SchemaCompatibilityStatus,
14
16
  type ITreeConfigurationOptions,
@@ -51,6 +53,7 @@ export {
51
53
  type JsonFieldSchema,
52
54
  type JsonLeafSchemaType,
53
55
  } from "./jsonSchema.js";
56
+ export type { TreeSchemaEncodingOptions } from "./getJsonSchema.js";
54
57
  export { getJsonSchema } from "./getJsonSchema.js";
55
58
  export { getSimpleSchema } from "./getSimpleSchema.js";
56
59
  export { ViewSchema } from "./view.js";
@@ -85,7 +88,6 @@ export type {
85
88
 
86
89
  export {
87
90
  type VerboseTreeNode,
88
- type ParseOptions,
89
91
  type VerboseTree,
90
92
  applySchemaToParserOptions,
91
93
  cursorFromVerbose,
@@ -94,7 +96,7 @@ export {
94
96
  } from "./verboseTree.js";
95
97
 
96
98
  export {
97
- type EncodeOptions,
99
+ type TreeEncodingOptions,
98
100
  customFromCursorStored,
99
101
  type CustomTreeNode,
100
102
  type CustomTreeValue,
@@ -69,7 +69,19 @@ export class SchemaFactoryAlpha<
69
69
  name: Name,
70
70
  fields: T,
71
71
  options?: SchemaFactoryObjectOptions<TCustomMetadata>,
72
- ): ObjectNodeSchema<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata> {
72
+ ): ObjectNodeSchema<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata> & {
73
+ /**
74
+ * Typing checking workaround: not for for actual use.
75
+ * @remarks
76
+ * This API collides with {@link TreeNodeSchemaCore.createFromInsertable} to disable a type checking optimization which produces different and undesired results.
77
+ * See {@link https://github.com/microsoft/TypeScript/issues/59049#issuecomment-2773459693} for more details.
78
+ * @privateRemarks
79
+ * The specific issue here is non-empty POJO mode object schema not being assignable to `ObjectNodeSchema`,
80
+ * See the above link and the tests in objectNode.spec.ts which reference it.
81
+ * @system
82
+ */
83
+ readonly createFromInsertable: unknown;
84
+ } {
73
85
  return objectSchema(
74
86
  this.scoped2(name),
75
87
  fields,
@@ -136,6 +148,11 @@ export class SchemaFactoryAlpha<
136
148
  >;
137
149
  }
138
150
 
151
+ /**
152
+ * {@inheritDoc SchemaStatics.optional}
153
+ */
154
+ public static override readonly leaves = schemaStatics.leaves;
155
+
139
156
  /**
140
157
  * {@inheritDoc SchemaStatics.optional}
141
158
  */
@@ -10,14 +10,15 @@ import {
10
10
  type AllowedTypes,
11
11
  type FieldSchemaAlpha,
12
12
  FieldKind,
13
+ type FieldProps,
13
14
  } from "../schemaTypes.js";
14
- import { SchemaFactory } from "./schemaFactory.js";
15
15
  import type {
16
16
  SimpleFieldSchema,
17
17
  SimpleNodeSchema,
18
18
  SimpleTreeSchema,
19
19
  } from "../simpleSchema.js";
20
20
  import { SchemaFactoryAlpha } from "./schemaFactoryAlpha.js";
21
+ import type { TreeSchema } from "./tree.js";
21
22
 
22
23
  const factory = new SchemaFactoryAlpha(undefined);
23
24
 
@@ -30,31 +31,53 @@ const factory = new SchemaFactoryAlpha(undefined);
30
31
  * will produce a poor TypeScript typing experience which is subject to change.
31
32
  *
32
33
  * Editing through a view produced using this schema can easily violate invariants other users of the document might expect and must be done with great care.
34
+ *
35
+ * This API bakes in some arbitrary policy choices for how to handle data that is not included in the SimpleTreeSchema API, for example the value of `allowUnknownOptionalFields`.
36
+ * If any particular choice is required for such cases, this API should not be used.
33
37
  * @alpha
34
38
  */
35
- export function generateSchemaFromSimpleSchema(simple: SimpleTreeSchema): FieldSchemaAlpha {
39
+ export function generateSchemaFromSimpleSchema(simple: SimpleTreeSchema): TreeSchema {
36
40
  const context: Context = new Map(
37
- [...simple.definitions].map(([id, schema]): [string, () => TreeNodeSchema] => [
38
- id,
39
- // This relies on the caching in evaluateLazySchema so that it only runs once.
40
- () => generateNode(id, schema, context),
41
- ]),
41
+ [...simple.definitions].map(
42
+ ([id, schema]): [string, () => TreeNodeSchema & SimpleNodeSchema] => [
43
+ id,
44
+ // This relies on the caching in evaluateLazySchema so that it only runs once.
45
+ () => generateNode(id, schema, context),
46
+ ],
47
+ ),
42
48
  );
43
- return generateFieldSchema(simple, context);
49
+ const root = generateFieldSchema(simple.root, context, undefined);
50
+ const definitions = new Map<string, TreeNodeSchema & SimpleNodeSchema>();
51
+ for (const [id, lazy] of context) {
52
+ definitions.set(id, lazy());
53
+ }
54
+ return {
55
+ root,
56
+ definitions,
57
+ };
44
58
  }
45
59
 
46
- type Context = ReadonlyMap<string, () => TreeNodeSchema>;
60
+ type Context = ReadonlyMap<string, () => TreeNodeSchema & SimpleNodeSchema>;
47
61
 
48
- function generateFieldSchema(simple: SimpleFieldSchema, context: Context): FieldSchemaAlpha {
62
+ function generateFieldSchema(
63
+ simple: SimpleFieldSchema,
64
+ context: Context,
65
+ storedKey: string | undefined,
66
+ ): FieldSchemaAlpha {
49
67
  const allowed = generateAllowedTypes(simple.allowedTypesIdentifiers, context);
68
+ const props: Omit<FieldProps, "defaultProvider"> = {
69
+ metadata: simple.metadata,
70
+ key: storedKey,
71
+ };
72
+
50
73
  // Using createFieldSchema could work, but would require setting up the default providers.
51
74
  switch (simple.kind) {
52
75
  case FieldKind.Identifier:
53
- return SchemaFactoryAlpha.identifier({ metadata: simple.metadata });
76
+ return SchemaFactoryAlpha.identifier(props);
54
77
  case FieldKind.Optional:
55
- return SchemaFactoryAlpha.optional(allowed, { metadata: simple.metadata });
78
+ return SchemaFactoryAlpha.optional(allowed, props);
56
79
  case FieldKind.Required:
57
- return SchemaFactoryAlpha.required(allowed, { metadata: simple.metadata });
80
+ return SchemaFactoryAlpha.required(allowed, props);
58
81
  default:
59
82
  return unreachableCase(simple.kind);
60
83
  }
@@ -64,13 +87,19 @@ function generateAllowedTypes(allowed: ReadonlySet<string>, context: Context): A
64
87
  return [...allowed].map((id) => context.get(id) ?? fail(0xb5a /* Missing schema */));
65
88
  }
66
89
 
67
- function generateNode(id: string, schema: SimpleNodeSchema, context: Context): TreeNodeSchema {
90
+ function generateNode(
91
+ id: string,
92
+ schema: SimpleNodeSchema,
93
+ context: Context,
94
+ ): TreeNodeSchema & SimpleNodeSchema {
68
95
  switch (schema.kind) {
69
96
  case NodeKind.Object: {
70
97
  const fields: Record<string, FieldSchema> = {};
71
98
  for (const [key, field] of schema.fields) {
72
- fields[key] = generateFieldSchema(field, context);
99
+ fields[key] = generateFieldSchema(field, context, field.storedKey);
73
100
  }
101
+ // Here allowUnknownOptionalFields is implicitly defaulting. This is a subjective policy choice:
102
+ // users of this code are expected to handle what ever choice this code makes for cases like this.
74
103
  return factory.object(id, fields, { metadata: schema.metadata });
75
104
  }
76
105
  case NodeKind.Array:
@@ -87,7 +116,7 @@ function generateNode(id: string, schema: SimpleNodeSchema, context: Context): T
87
116
  );
88
117
  case NodeKind.Leaf:
89
118
  return (
90
- SchemaFactory.leaves.find((leaf) => leaf.identifier === id) ??
119
+ SchemaFactoryAlpha.leaves.find((leaf) => leaf.identifier === id) ??
91
120
  fail(0xb5b /* Missing schema */)
92
121
  );
93
122
  default:
@@ -6,7 +6,7 @@
6
6
  import { unreachableCase } from "@fluidframework/core-utils/internal";
7
7
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
8
8
  import { ValueSchema } from "../../core/index.js";
9
- import { copyProperty, getOrCreate, hasSingle, type Mutable } from "../../util/index.js";
9
+ import { copyProperty, hasSingle, type Mutable } from "../../util/index.js";
10
10
  import type {
11
11
  JsonArrayNodeSchema,
12
12
  JsonFieldSchema,
@@ -24,24 +24,39 @@ import type {
24
24
  SimpleArrayNodeSchema,
25
25
  SimpleLeafNodeSchema,
26
26
  SimpleMapNodeSchema,
27
- SimpleNodeSchema,
28
- SimpleObjectNodeSchema,
29
- SimpleTreeSchema,
30
27
  } from "../simpleSchema.js";
31
- import { NodeKind } from "../core/index.js";
28
+ import { NodeKind, type TreeNodeSchema } from "../core/index.js";
29
+ import type { TreeSchema } from "./tree.js";
30
+ import type { TreeSchemaEncodingOptions } from "./getJsonSchema.js";
31
+ import { ObjectNodeSchema } from "../objectNodeTypes.js";
32
+ import { ArrayNodeSchema } from "../arrayNodeTypes.js";
33
+ import { MapNodeSchema } from "../mapNodeTypes.js";
34
+ import { LeafNodeSchema } from "../leafNodeSchema.js";
32
35
 
33
36
  /**
34
37
  * Generates a JSON Schema representation from a simple tree schema.
38
+ * @remarks
39
+ * This expects the data to be in the {@link ConciseTree} format.
40
+ *
41
+ * This cannot handle the case where the root is undefined since undefined is not a concept in JSON.
42
+ * This also cannot handle {@link SchemaStatics.handle} since they also are not supported in JSON.
43
+ *
35
44
  * @internal
36
45
  */
37
- export function toJsonSchema(schema: SimpleTreeSchema): JsonTreeSchema {
38
- const definitions = convertDefinitions(schema.definitions);
46
+ export function toJsonSchema(
47
+ schema: TreeSchema,
48
+ options: Required<TreeSchemaEncodingOptions>,
49
+ ): JsonTreeSchema {
50
+ const definitions = convertDefinitions(schema.definitions, options);
39
51
 
40
52
  const allowedTypes: JsonSchemaRef[] = [];
41
- for (const allowedType of schema.allowedTypesIdentifiers) {
53
+ for (const allowedType of schema.root.allowedTypesIdentifiers) {
42
54
  allowedTypes.push(createSchemaRef(allowedType));
43
55
  }
44
56
 
57
+ // TODO: deduplicate field handling logic from convertObjectNodeSchema: at least include metadata's description.
58
+ // TODO: maybe account for consider schema.kind, or just take in ImplicitAllowedTypes
59
+ // TODO: handle case where allowedTypes is empty.
45
60
  return hasSingle(allowedTypes)
46
61
  ? {
47
62
  ...allowedTypes[0],
@@ -54,40 +69,35 @@ export function toJsonSchema(schema: SimpleTreeSchema): JsonTreeSchema {
54
69
  }
55
70
 
56
71
  function convertDefinitions(
57
- definitions: ReadonlyMap<string, SimpleNodeSchema>,
72
+ definitions: ReadonlyMap<string, TreeNodeSchema>,
73
+ options: Required<TreeSchemaEncodingOptions>,
58
74
  ): Record<string, JsonNodeSchema> {
59
75
  const result: Record<string, JsonNodeSchema> = {};
60
76
  for (const [key, value] of definitions) {
61
- result[key] = convertNodeSchema(value);
77
+ result[key] = convertNodeSchema(value, options);
62
78
  }
63
79
  return result;
64
80
  }
65
81
 
66
- /**
67
- * Private symbol under which the results of {@link convertNodeSchema} are cached on an input {@link SimpleNodeSchema}.
68
- */
69
- const nodeJsonSchemaCache = new WeakMap<SimpleNodeSchema, JsonNodeSchema>();
70
-
71
82
  /**
72
83
  * Converts an input {@link SimpleNodeSchema} to a {@link JsonNodeSchema}.
73
84
  *
74
85
  * @remarks Caches the result on the input schema for future calls.
75
86
  */
76
- function convertNodeSchema(schema: SimpleNodeSchema): JsonNodeSchema {
77
- return getOrCreate(nodeJsonSchemaCache, schema, () => {
78
- switch (schema.kind) {
79
- case NodeKind.Array:
80
- return convertArrayNodeSchema(schema);
81
- case NodeKind.Leaf:
82
- return convertLeafNodeSchema(schema);
83
- case NodeKind.Map:
84
- return convertMapNodeSchema(schema);
85
- case NodeKind.Object:
86
- return convertObjectNodeSchema(schema);
87
- default:
88
- throw new TypeError(`Unknown node schema kind: ${(schema as SimpleNodeSchema).kind}`);
89
- }
90
- });
87
+ function convertNodeSchema(
88
+ schema: TreeNodeSchema,
89
+ options: Required<TreeSchemaEncodingOptions>,
90
+ ): JsonNodeSchema {
91
+ if (schema instanceof ArrayNodeSchema) {
92
+ return convertArrayNodeSchema(schema);
93
+ } else if (schema instanceof MapNodeSchema) {
94
+ return convertMapNodeSchema(schema);
95
+ } else if (schema instanceof ObjectNodeSchema) {
96
+ return convertObjectNodeSchema(schema, options);
97
+ } else if (schema instanceof LeafNodeSchema) {
98
+ return convertLeafNodeSchema(schema);
99
+ }
100
+ throw new TypeError(`Unknown node schema kind: ${schema.kind}`);
91
101
  }
92
102
 
93
103
  function convertArrayNodeSchema(schema: SimpleArrayNodeSchema): JsonArrayNodeSchema {
@@ -138,10 +148,14 @@ function convertLeafNodeSchema(schema: SimpleLeafNodeSchema): JsonLeafNodeSchema
138
148
  };
139
149
  }
140
150
 
141
- export function convertObjectNodeSchema(schema: SimpleObjectNodeSchema): JsonObjectNodeSchema {
151
+ export function convertObjectNodeSchema(
152
+ schema: ObjectNodeSchema,
153
+ options: Required<TreeSchemaEncodingOptions>,
154
+ ): JsonObjectNodeSchema {
142
155
  const properties: Record<string, JsonFieldSchema> = {};
143
156
  const required: string[] = [];
144
- for (const [key, fieldSchema] of schema.fields) {
157
+ for (const [propertyKey, fieldSchema] of schema.fields) {
158
+ const key = options.useStoredKeys ? fieldSchema.storedKey : propertyKey;
145
159
  const allowedTypes: JsonSchemaRef[] = [];
146
160
  for (const allowedType of fieldSchema.allowedTypesIdentifiers) {
147
161
  allowedTypes.push(createSchemaRef(allowedType));
@@ -156,8 +170,13 @@ export function convertObjectNodeSchema(schema: SimpleObjectNodeSchema): JsonObj
156
170
  copyProperty(fieldSchema.metadata, "description", output);
157
171
  properties[key] = output;
158
172
 
159
- if (fieldSchema.kind === FieldKind.Required) {
160
- required.push(key);
173
+ if (fieldSchema.kind !== FieldKind.Optional) {
174
+ if (
175
+ options.requireFieldsWithDefaults ||
176
+ fieldSchema.props?.defaultProvider === undefined
177
+ ) {
178
+ required.push(key);
179
+ }
161
180
  }
162
181
  }
163
182
 
@@ -20,6 +20,7 @@ import type {
20
20
  } from "../../shared-tree/index.js";
21
21
 
22
22
  import {
23
+ type FieldSchemaAlpha,
23
24
  type ImplicitFieldSchema,
24
25
  type InsertableField,
25
26
  type InsertableTreeFieldFromImplicitField,
@@ -29,6 +30,7 @@ import {
29
30
  type UnsafeUnknownSchema,
30
31
  FieldKind,
31
32
  markSchemaMostDerived,
33
+ normalizeFieldSchema,
32
34
  } from "../schemaTypes.js";
33
35
  import { NodeKind, type TreeNodeSchema } from "../core/index.js";
34
36
  import { toStoredSchema } from "../toStoredSchema.js";
@@ -38,7 +40,7 @@ import { getOrCreate } from "../../util/index.js";
38
40
  import type { MakeNominal } from "../../util/index.js";
39
41
  import { walkFieldSchema } from "../walkFieldSchema.js";
40
42
  import type { VerboseTree } from "./verboseTree.js";
41
- import type { SimpleTreeSchema } from "../simpleSchema.js";
43
+ import type { SimpleNodeSchema, SimpleTreeSchema } from "../simpleSchema.js";
42
44
  import type {
43
45
  RunTransactionParams,
44
46
  TransactionCallbackStatus,
@@ -106,9 +108,7 @@ export interface ITree extends ViewableTree, IFluidLoadable {}
106
108
 
107
109
  /**
108
110
  * {@link ITree} extended with some alpha APIs.
109
- * @privateRemarks
110
- * TODO: Promote this to alpha.
111
- * @internal
111
+ * @sealed @alpha
112
112
  */
113
113
  export interface ITreeAlpha extends ITree {
114
114
  /**
@@ -309,6 +309,53 @@ export class TreeViewConfiguration<
309
309
  }
310
310
  }
311
311
 
312
+ /**
313
+ * {@link TreeViewConfiguration} extended with some alpha APIs.
314
+ * @sealed @alpha
315
+ */
316
+ export class TreeViewConfigurationAlpha<
317
+ const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,
318
+ >
319
+ extends TreeViewConfiguration<TSchema>
320
+ implements TreeSchema
321
+ {
322
+ /**
323
+ * {@inheritDoc TreeSchema.root}
324
+ */
325
+ public readonly root: FieldSchemaAlpha;
326
+ /**
327
+ * {@inheritDoc TreeSchema.definitions}
328
+ */
329
+ public readonly definitions: ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema>;
330
+
331
+ public constructor(props: ITreeViewConfiguration<TSchema>) {
332
+ super(props);
333
+ this.root = normalizeFieldSchema(props.schema);
334
+ const definitions = new Map<string, SimpleNodeSchema & TreeNodeSchema>();
335
+ walkFieldSchema(props.schema, {
336
+ node: (schema) =>
337
+ definitions.set(schema.identifier, schema as SimpleNodeSchema & TreeNodeSchema),
338
+ });
339
+ this.definitions = definitions;
340
+ }
341
+ }
342
+
343
+ /**
344
+ * {@link TreeViewConfigurationAlpha}
345
+ * @sealed @alpha
346
+ */
347
+ export interface TreeSchema extends SimpleTreeSchema {
348
+ /**
349
+ * {@inheritDoc SimpleTreeSchema.root}
350
+ */
351
+ readonly root: FieldSchemaAlpha;
352
+
353
+ /**
354
+ * {@inheritDoc SimpleTreeSchema.definitions}
355
+ */
356
+ readonly definitions: ReadonlyMap<string, SimpleNodeSchema & TreeNodeSchema>;
357
+ }
358
+
312
359
  /**
313
360
  * Pretty print a set of types for use in error messages.
314
361
  */