@fluidframework/tree 2.90.0 → 2.91.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 (240) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/alpha.d.ts +2 -2
  3. package/api-extractor/api-extractor-lint-alpha.cjs.json +1 -1
  4. package/api-extractor/api-extractor-lint-alpha.esm.json +1 -1
  5. package/api-extractor/api-extractor-lint-beta.cjs.json +1 -1
  6. package/api-extractor/api-extractor-lint-beta.esm.json +1 -1
  7. package/api-extractor/api-extractor-lint-bundle.json +1 -1
  8. package/api-extractor/api-extractor-lint-legacy.cjs.json +1 -1
  9. package/api-extractor/api-extractor-lint-legacy.esm.json +1 -1
  10. package/api-extractor/api-extractor-lint-public.cjs.json +1 -1
  11. package/api-extractor/api-extractor-lint-public.esm.json +1 -1
  12. package/api-extractor/api-extractor.current.json +1 -1
  13. package/api-extractor/api-extractor.legacy.json +2 -1
  14. package/api-extractor.json +1 -0
  15. package/api-report/tree.alpha.api.md +81 -15
  16. package/beta.d.ts +2 -2
  17. package/dist/entrypoints/alpha.d.ts +6 -0
  18. package/dist/entrypoints/alpha.d.ts.map +1 -0
  19. package/dist/entrypoints/alpha.js +92 -0
  20. package/dist/entrypoints/alpha.js.map +1 -0
  21. package/dist/entrypoints/beta.d.ts +6 -0
  22. package/dist/entrypoints/beta.d.ts.map +1 -0
  23. package/dist/entrypoints/beta.js +43 -0
  24. package/dist/entrypoints/beta.js.map +1 -0
  25. package/dist/entrypoints/internal.d.ts +6 -0
  26. package/dist/entrypoints/internal.d.ts.map +1 -0
  27. package/dist/entrypoints/internal.js +28 -0
  28. package/dist/entrypoints/internal.js.map +1 -0
  29. package/dist/entrypoints/legacy.d.ts +6 -0
  30. package/dist/entrypoints/legacy.d.ts.map +1 -0
  31. package/dist/entrypoints/legacy.js +49 -0
  32. package/dist/entrypoints/legacy.js.map +1 -0
  33. package/dist/entrypoints/public.d.ts +6 -0
  34. package/dist/entrypoints/public.d.ts.map +1 -0
  35. package/dist/entrypoints/public.js +27 -0
  36. package/dist/entrypoints/public.js.map +1 -0
  37. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +3 -3
  38. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  39. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  40. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +1 -0
  41. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -1
  42. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js +14 -6
  43. package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -1
  44. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  45. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +7 -3
  46. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  47. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  48. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  49. package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  50. package/dist/index.d.ts +7 -1
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +2 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/packageVersion.d.ts +1 -1
  55. package/dist/packageVersion.js +1 -1
  56. package/dist/packageVersion.js.map +1 -1
  57. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  58. package/dist/shared-tree/treeCheckout.js +2 -1
  59. package/dist/shared-tree/treeCheckout.js.map +1 -1
  60. package/dist/simple-tree/api/eraseSchemaDetails.d.ts +43 -0
  61. package/dist/simple-tree/api/eraseSchemaDetails.d.ts.map +1 -1
  62. package/dist/simple-tree/api/eraseSchemaDetails.js.map +1 -1
  63. package/dist/simple-tree/api/index.d.ts +3 -2
  64. package/dist/simple-tree/api/index.d.ts.map +1 -1
  65. package/dist/simple-tree/api/index.js.map +1 -1
  66. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  67. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  68. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +125 -28
  69. package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  70. package/dist/simple-tree/api/schemaFactoryAlpha.js +72 -7
  71. package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  72. package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  73. package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  74. package/dist/simple-tree/api/schemaStatics.d.ts +10 -11
  75. package/dist/simple-tree/api/schemaStatics.d.ts.map +1 -1
  76. package/dist/simple-tree/api/schemaStatics.js +13 -7
  77. package/dist/simple-tree/api/schemaStatics.js.map +1 -1
  78. package/dist/simple-tree/api/typesUnsafe.d.ts +23 -2
  79. package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  80. package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
  81. package/dist/simple-tree/fieldSchema.d.ts +3 -2
  82. package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
  83. package/dist/simple-tree/fieldSchema.js +3 -4
  84. package/dist/simple-tree/fieldSchema.js.map +1 -1
  85. package/dist/simple-tree/index.d.ts +2 -2
  86. package/dist/simple-tree/index.d.ts.map +1 -1
  87. package/dist/simple-tree/index.js.map +1 -1
  88. package/dist/simple-tree/node-kinds/index.d.ts +1 -1
  89. package/dist/simple-tree/node-kinds/index.d.ts.map +1 -1
  90. package/dist/simple-tree/node-kinds/index.js.map +1 -1
  91. package/dist/simple-tree/node-kinds/object/index.d.ts +2 -2
  92. package/dist/simple-tree/node-kinds/object/index.d.ts.map +1 -1
  93. package/dist/simple-tree/node-kinds/object/index.js.map +1 -1
  94. package/dist/simple-tree/node-kinds/object/objectNode.d.ts +43 -7
  95. package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  96. package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  97. package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts +26 -2
  98. package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
  99. package/dist/simple-tree/node-kinds/object/objectNodeTypes.js.map +1 -1
  100. package/dist/text/textDomainFormatted.d.ts +2 -4
  101. package/dist/text/textDomainFormatted.d.ts.map +1 -1
  102. package/dist/util/rangeMap.d.ts +25 -18
  103. package/dist/util/rangeMap.d.ts.map +1 -1
  104. package/dist/util/rangeMap.js +24 -30
  105. package/dist/util/rangeMap.js.map +1 -1
  106. package/dist/util/typeCheck.d.ts.map +1 -1
  107. package/dist/util/typeCheck.js.map +1 -1
  108. package/dist/util/typeUtils.d.ts.map +1 -1
  109. package/dist/util/typeUtils.js.map +1 -1
  110. package/eslint.config.mts +10 -2
  111. package/internal.d.ts +2 -2
  112. package/legacy.d.ts +4 -3
  113. package/lib/entrypoints/alpha.d.ts +6 -0
  114. package/lib/entrypoints/alpha.d.ts.map +1 -0
  115. package/lib/entrypoints/alpha.js +12 -0
  116. package/lib/entrypoints/alpha.js.map +1 -0
  117. package/lib/entrypoints/beta.d.ts +6 -0
  118. package/lib/entrypoints/beta.d.ts.map +1 -0
  119. package/lib/entrypoints/beta.js +12 -0
  120. package/lib/entrypoints/beta.js.map +1 -0
  121. package/lib/entrypoints/internal.d.ts +6 -0
  122. package/lib/entrypoints/internal.d.ts.map +1 -0
  123. package/lib/entrypoints/internal.js +12 -0
  124. package/lib/entrypoints/internal.js.map +1 -0
  125. package/lib/entrypoints/legacy.d.ts +6 -0
  126. package/lib/entrypoints/legacy.d.ts.map +1 -0
  127. package/lib/entrypoints/legacy.js +15 -0
  128. package/lib/entrypoints/legacy.js.map +1 -0
  129. package/lib/entrypoints/public.d.ts +6 -0
  130. package/lib/entrypoints/public.d.ts.map +1 -0
  131. package/lib/entrypoints/public.js +10 -0
  132. package/lib/entrypoints/public.js.map +1 -0
  133. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +3 -3
  134. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  135. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  136. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +1 -0
  137. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -1
  138. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js +14 -6
  139. package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -1
  140. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  141. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +7 -3
  142. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  143. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  144. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  145. package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  146. package/lib/index.d.ts +7 -1
  147. package/lib/index.d.ts.map +1 -1
  148. package/lib/index.js +8 -0
  149. package/lib/index.js.map +1 -1
  150. package/lib/packageVersion.d.ts +1 -1
  151. package/lib/packageVersion.js +1 -1
  152. package/lib/packageVersion.js.map +1 -1
  153. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  154. package/lib/shared-tree/treeCheckout.js +2 -1
  155. package/lib/shared-tree/treeCheckout.js.map +1 -1
  156. package/lib/simple-tree/api/eraseSchemaDetails.d.ts +43 -0
  157. package/lib/simple-tree/api/eraseSchemaDetails.d.ts.map +1 -1
  158. package/lib/simple-tree/api/eraseSchemaDetails.js.map +1 -1
  159. package/lib/simple-tree/api/index.d.ts +3 -2
  160. package/lib/simple-tree/api/index.d.ts.map +1 -1
  161. package/lib/simple-tree/api/index.js +1 -1
  162. package/lib/simple-tree/api/index.js.map +1 -1
  163. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  164. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  165. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +125 -28
  166. package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
  167. package/lib/simple-tree/api/schemaFactoryAlpha.js +66 -1
  168. package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
  169. package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -1
  170. package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -1
  171. package/lib/simple-tree/api/schemaStatics.d.ts +10 -11
  172. package/lib/simple-tree/api/schemaStatics.d.ts.map +1 -1
  173. package/lib/simple-tree/api/schemaStatics.js +14 -8
  174. package/lib/simple-tree/api/schemaStatics.js.map +1 -1
  175. package/lib/simple-tree/api/typesUnsafe.d.ts +23 -2
  176. package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
  177. package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
  178. package/lib/simple-tree/fieldSchema.d.ts +3 -2
  179. package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
  180. package/lib/simple-tree/fieldSchema.js +3 -4
  181. package/lib/simple-tree/fieldSchema.js.map +1 -1
  182. package/lib/simple-tree/index.d.ts +2 -2
  183. package/lib/simple-tree/index.d.ts.map +1 -1
  184. package/lib/simple-tree/index.js.map +1 -1
  185. package/lib/simple-tree/node-kinds/index.d.ts +1 -1
  186. package/lib/simple-tree/node-kinds/index.d.ts.map +1 -1
  187. package/lib/simple-tree/node-kinds/index.js.map +1 -1
  188. package/lib/simple-tree/node-kinds/object/index.d.ts +2 -2
  189. package/lib/simple-tree/node-kinds/object/index.d.ts.map +1 -1
  190. package/lib/simple-tree/node-kinds/object/index.js.map +1 -1
  191. package/lib/simple-tree/node-kinds/object/objectNode.d.ts +43 -7
  192. package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
  193. package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
  194. package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts +26 -2
  195. package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
  196. package/lib/simple-tree/node-kinds/object/objectNodeTypes.js.map +1 -1
  197. package/lib/text/textDomainFormatted.d.ts +2 -4
  198. package/lib/text/textDomainFormatted.d.ts.map +1 -1
  199. package/lib/util/rangeMap.d.ts +25 -18
  200. package/lib/util/rangeMap.d.ts.map +1 -1
  201. package/lib/util/rangeMap.js +25 -31
  202. package/lib/util/rangeMap.js.map +1 -1
  203. package/lib/util/typeCheck.d.ts.map +1 -1
  204. package/lib/util/typeCheck.js.map +1 -1
  205. package/lib/util/typeUtils.d.ts.map +1 -1
  206. package/lib/util/typeUtils.js.map +1 -1
  207. package/package.json +46 -46
  208. package/scripts/generate-entrypoint-sources.sh +29 -0
  209. package/{dist/alpha.d.ts → src/entrypoints/alpha.ts} +12 -5
  210. package/{lib/beta.d.ts → src/entrypoints/beta.ts} +2 -5
  211. package/src/entrypoints/internal.ts +13 -0
  212. package/{dist/legacy.d.ts → src/entrypoints/legacy.ts} +2 -5
  213. package/{lib/public.d.ts → src/entrypoints/public.ts} +2 -5
  214. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +3 -8
  215. package/src/feature-libraries/modular-schema/defaultRevisionReplacer.ts +16 -8
  216. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +9 -4
  217. package/src/feature-libraries/sequence-field/moveEffectTable.ts +1 -1
  218. package/src/index.ts +19 -0
  219. package/src/packageVersion.ts +1 -1
  220. package/src/shared-tree/treeCheckout.ts +2 -1
  221. package/src/simple-tree/api/eraseSchemaDetails.ts +60 -0
  222. package/src/simple-tree/api/index.ts +12 -1
  223. package/src/simple-tree/api/schemaFactory.ts +8 -1
  224. package/src/simple-tree/api/schemaFactoryAlpha.ts +262 -25
  225. package/src/simple-tree/api/schemaFactoryBeta.ts +10 -1
  226. package/src/simple-tree/api/schemaStatics.ts +79 -21
  227. package/src/simple-tree/api/typesUnsafe.ts +49 -1
  228. package/src/simple-tree/fieldSchema.ts +29 -5
  229. package/src/simple-tree/index.ts +10 -0
  230. package/src/simple-tree/node-kinds/index.ts +3 -0
  231. package/src/simple-tree/node-kinds/object/index.ts +3 -0
  232. package/src/simple-tree/node-kinds/object/objectNode.ts +69 -11
  233. package/src/simple-tree/node-kinds/object/objectNodeTypes.ts +33 -2
  234. package/src/util/rangeMap.ts +54 -50
  235. package/src/util/typeCheck.ts +1 -0
  236. package/src/util/typeUtils.ts +4 -7
  237. package/dist/beta.d.ts +0 -152
  238. package/dist/public.d.ts +0 -94
  239. package/lib/alpha.d.ts +0 -304
  240. package/lib/legacy.d.ts +0 -159
@@ -9,10 +9,6 @@
9
9
  */
10
10
 
11
11
  export {
12
- // #region Unrestricted APIs
13
- InternalTypes,
14
- // #endregion
15
-
16
12
  // #region @public APIs
17
13
  AllowedTypes,
18
14
  CommitKind,
@@ -32,6 +28,7 @@ export {
32
28
  InsertableTreeNodeFromImplicitAllowedTypes,
33
29
  InsertableTypedNode,
34
30
  InternalTreeNode,
31
+ InternalTypes,
35
32
  IsListener,
36
33
  IsUnion,
37
34
  IterableTreeArrayContent,
@@ -156,4 +153,4 @@ export {
156
153
  SharedTreeFactoryType,
157
154
  configuredSharedTreeBetaLegacy
158
155
  // #endregion
159
- } from "./index.js";
156
+ } from "../index.js";
@@ -9,10 +9,6 @@
9
9
  */
10
10
 
11
11
  export {
12
- // #region Unrestricted APIs
13
- InternalTypes,
14
- // #endregion
15
-
16
12
  // #region @public APIs
17
13
  AllowedTypes,
18
14
  CommitKind,
@@ -32,6 +28,7 @@ export {
32
28
  InsertableTreeNodeFromImplicitAllowedTypes,
33
29
  InsertableTypedNode,
34
30
  InternalTreeNode,
31
+ InternalTypes,
35
32
  IsListener,
36
33
  IsUnion,
37
34
  IterableTreeArrayContent,
@@ -91,4 +88,4 @@ export {
91
88
  rollback,
92
89
  typeSchemaSymbol
93
90
  // #endregion
94
- } from "./index.js";
91
+ } from "../index.js";
@@ -3,12 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type {
7
- ChangeAtomId,
8
- ChangeAtomIdRangeMap,
9
- ChangesetLocalId,
10
- RevisionTag,
11
- } from "../../core/index.js";
6
+ import type { ChangeAtomIdRangeMap, ChangesetLocalId, RevisionTag } from "../../core/index.js";
12
7
  import type { RangeQueryResult } from "../../util/index.js";
13
8
 
14
9
  import type { NodeId } from "./modularChangeTypes.js";
@@ -40,7 +35,7 @@ export function getFirstFromCrossFieldMap<T>(
40
35
  revision: RevisionTag | undefined,
41
36
  id: ChangesetLocalId,
42
37
  count: number,
43
- ): RangeQueryResult<ChangeAtomId, T> {
38
+ ): RangeQueryResult<T | undefined> {
44
39
  return map.getFirst({ revision, localId: id }, count);
45
40
  }
46
41
 
@@ -64,7 +59,7 @@ export interface CrossFieldManager<T = unknown> {
64
59
  id: ChangesetLocalId,
65
60
  count: number,
66
61
  addDependency: boolean,
67
- ): RangeQueryResult<ChangeAtomId, T>;
62
+ ): RangeQueryResult<T | undefined>;
68
63
 
69
64
  /**
70
65
  * Sets the range of keys to `newValue`.
@@ -60,14 +60,13 @@ export class DefaultRevisionReplacer implements RevisionReplacer {
60
60
  const prior = this.updatedLocalIds.getFirst(remainderStart, remainderCount);
61
61
  if (prior.value === undefined) {
62
62
  const defaultOutputId = continuingOutputId ?? remainderStart.localId;
63
- const newLocalId =
64
- this.localIds.getAll(defaultOutputId, prior.length).length > 0
65
- ? // Some of the IDs in this range have already been used in the scope of the updated revision.
66
- // We need to allocate new local IDs.
67
- brand<ChangesetLocalId>(this.maxSeen + 1)
68
- : // This change atom ID uses a local ID that has not yet been used in the scope of the updated revision.
69
- // We reuse it as is to minimize the number of IDs that need to be updated.
70
- defaultOutputId;
63
+ const newLocalId = this.areAllUnallocated(defaultOutputId, prior.length)
64
+ ? // This change atom ID uses a local ID that has not yet been used in the scope of the updated revision.
65
+ // We reuse it as is to minimize the number of IDs that need to be updated.
66
+ defaultOutputId
67
+ : // Some of the IDs in this range have already been used in the scope of the updated revision.
68
+ // We need to allocate new local IDs.
69
+ brand<ChangesetLocalId>(this.maxSeen + 1);
71
70
 
72
71
  this.maxSeen = brand(Math.max(this.maxSeen, newLocalId + prior.length - 1));
73
72
  this.localIds.set(newLocalId, prior.length, true);
@@ -93,4 +92,13 @@ export class DefaultRevisionReplacer implements RevisionReplacer {
93
92
  }
94
93
  return id;
95
94
  }
95
+
96
+ private areAllUnallocated(id: ChangesetLocalId, count: number): boolean {
97
+ for (const entry of this.localIds.getAll(id, count)) {
98
+ if (entry.value !== undefined) {
99
+ return false;
100
+ }
101
+ }
102
+ return true;
103
+ }
96
104
  }
@@ -2387,7 +2387,7 @@ abstract class CrossFieldManagerI<T> implements CrossFieldManager {
2387
2387
  id: ChangesetLocalId,
2388
2388
  count: number,
2389
2389
  addDependency: boolean,
2390
- ): RangeQueryResult<ChangeAtomId, unknown> {
2390
+ ): RangeQueryResult<unknown> {
2391
2391
  if (addDependency) {
2392
2392
  // We assume that if there is already an entry for this ID it is because
2393
2393
  // a field handler has called compose on the same node multiple times.
@@ -3148,9 +3148,14 @@ function getFieldsForCrossFieldKey(
3148
3148
  key: CrossFieldKey,
3149
3149
  count: number,
3150
3150
  ): FieldId[] {
3151
- return changeset.crossFieldKeys
3152
- .getAll(key, count)
3153
- .map(({ value: fieldId }) => normalizeFieldId(fieldId, changeset.nodeAliases));
3151
+ const fieldIds: FieldId[] = [];
3152
+ for (const { value: fieldId } of changeset.crossFieldKeys.getAll(key, count)) {
3153
+ if (fieldId !== undefined) {
3154
+ fieldIds.push(normalizeFieldId(fieldId, changeset.nodeAliases));
3155
+ }
3156
+ }
3157
+
3158
+ return fieldIds;
3154
3159
  }
3155
3160
 
3156
3161
  // This is only exported for use in test utilities.
@@ -101,7 +101,7 @@ export function getMoveEffect(
101
101
  id: MoveId,
102
102
  count: number,
103
103
  addDependency: boolean = true,
104
- ): RangeQueryResult<ChangeAtomId, MoveEffect> {
104
+ ): RangeQueryResult<MoveEffect | undefined> {
105
105
  const result = moveEffects.get(target, revision, id, count, addDependency);
106
106
  return result.value === undefined
107
107
  ? result
package/src/index.ts CHANGED
@@ -3,6 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ // For the time being, if exports are changed, additional files under entrypoints need updated.
7
+ // Run `pnpm generate:entrypoint-sources` to update them.
8
+
6
9
  export {
7
10
  ValueSchema,
8
11
  type Revertible,
@@ -122,6 +125,7 @@ export {
122
125
  NodeKind,
123
126
  type TreeObjectNode,
124
127
  ObjectNodeSchema,
128
+ type ObjectNodeSchemaWorkaround,
125
129
  type TreeNodeFromImplicitAllowedTypes,
126
130
  type TreeNodeSchemaClass,
127
131
  type SchemaCompatibilityStatus,
@@ -144,6 +148,8 @@ export {
144
148
  type AllowedTypes,
145
149
  type System_Unsafe,
146
150
  type FieldSchemaAlphaUnsafe,
151
+ type FieldHasDefaultAlphaUnsafe,
152
+ type InsertableObjectFromSchemaRecordAlphaUnsafe,
147
153
  type ArrayNodeCustomizableSchemaUnsafe,
148
154
  type MapNodeCustomizableSchemaUnsafe,
149
155
  type TreeRecordNodeUnsafe,
@@ -192,6 +198,10 @@ export {
192
198
  type AllowedTypesFull,
193
199
  type AllowedTypesFullFromMixed,
194
200
  type SchemaType,
201
+ type SchemaStaticsAlpha,
202
+ type NodeProvider,
203
+ type InsertableObjectFromSchemaRecordAlpha,
204
+ type FieldHasDefaultAlpha,
195
205
  // Beta APIs
196
206
  TreeBeta,
197
207
  type TreeChangeEventsBeta,
@@ -303,6 +313,9 @@ export {
303
313
  incrementalEncodingPolicyForAllowedTypes,
304
314
  eraseSchemaDetails,
305
315
  eraseSchemaDetailsSubclassable,
316
+ type ErasedSchema,
317
+ type ErasedNode,
318
+ type ErasedSchemaSubclassable,
306
319
  type SnapshotSchemaCompatibilityOptions,
307
320
  type ArrayPlaceAnchor,
308
321
  createArrayInsertionAnchor,
@@ -359,6 +372,12 @@ import * as InternalTypes from "./internalTypes.js";
359
372
  /**
360
373
  * Contains types used by the API, but which serve mechanical purposes and do not represent semantic concepts.
361
374
  * They are used internally to implement API aspects, but are not intended for use by external consumers.
375
+ *
376
+ * @public
377
+ * @system
378
+ *
379
+ * @privateRemarks These TS-Docs are not recognized by API-Extractor, but the
380
+ * support level tag is recognized by flub entrypoint generation.
362
381
  */
363
382
  // eslint-disable-next-line unicorn/prefer-export-from -- fixing requires `export * as` (breaks API-Extractor)
364
383
  export { InternalTypes };
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/tree";
9
- export const pkgVersion = "2.90.0";
9
+ export const pkgVersion = "2.91.0";
@@ -786,7 +786,8 @@ export class TreeCheckout implements ITreeCheckoutFork {
786
786
  revision,
787
787
  };
788
788
  const decodedChange = this.changeFamily.codecs.resolve(4).decode(change, context);
789
- this.applyChange(decodedChange, revision);
789
+ // Apply the change to the branch, but _not_ the `activeBranch` - we do not support squashing serialized commits in a transaction.
790
+ this.#transaction.branch.apply(tagChange(decodedChange, revision));
790
791
  }
791
792
 
792
793
  // Revision is the revision of the commit, if any, which caused this change.
@@ -121,3 +121,63 @@ export function eraseSchemaDetailsSubclassable<TNode, ExtraSchemaProperties = un
121
121
  > {
122
122
  return (schema) => schema as never;
123
123
  }
124
+
125
+ /**
126
+ * The type of an erased schema.
127
+ * @remarks
128
+ * Provides an {@link https://www.typescriptlang.org/tsconfig/#isolatedDeclarations | isolatedDeclarations}
129
+ * compatible way to explicitly type the return value from {@link eraseSchemaDetails}.
130
+ * @example
131
+ * ```typescript
132
+ * export const Square: SquareSchema & ErasedSchema<Square> = eraseSchemaDetails<Square, SquareSchema>()(SquareInternal);
133
+ * export type Square = ErasedNode<SquareNode, "com.example.Demo">;
134
+ * ```
135
+ * @alpha
136
+ */
137
+ export type ErasedSchema<NodeType extends TreeNode> = TreeNodeSchema<
138
+ NodeType extends WithType<infer Identifier> ? Identifier : string,
139
+ NodeKind,
140
+ NodeType,
141
+ never,
142
+ false
143
+ >;
144
+
145
+ /**
146
+ * The type of an erased schema's node.
147
+ * @remarks
148
+ * Provides a way to concisely and explicitly type the node type for a schema returned from {@link eraseSchemaDetails}.
149
+ * @example
150
+ * ```typescript
151
+ * export const Square: SquareSchema & ErasedSchema<Square> = eraseSchemaDetails<Square, SquareSchema>()(SquareInternal);
152
+ * export type Square = ErasedNode<SquareNode, "com.example.Demo">;
153
+ * ```
154
+ * @alpha
155
+ */
156
+ export type ErasedNode<TExtra, Identifier extends string> = TExtra &
157
+ TreeNode &
158
+ WithType<Identifier>;
159
+
160
+ /**
161
+ * The type of a subclassable erased schema.
162
+ * @remarks
163
+ * Provides an {@link https://www.typescriptlang.org/tsconfig/#isolatedDeclarations | isolatedDeclarations}
164
+ * compatible way to explicitly type the return value from {@link eraseSchemaDetailsSubclassable}.
165
+ * @example
166
+ * ```typescript
167
+ * export const SquareSubclassable: SquareSchema &
168
+ * ErasedSchemaSubclassable<SquareNode, "com.example.Demo"> = eraseSchemaDetailsSubclassable<
169
+ * Square,
170
+ * SquareSchema
171
+ * >()(SquareInternal);
172
+ *
173
+ * class SquareSubclass extends SquareSubclassable {}
174
+ * ```
175
+ * @alpha
176
+ */
177
+ export type ErasedSchemaSubclassable<TExtra, Identifier extends string> = TreeNodeSchemaClass<
178
+ Identifier,
179
+ NodeKind,
180
+ ErasedNode<TExtra, Identifier>,
181
+ never,
182
+ false
183
+ >;
@@ -38,11 +38,20 @@ export {
38
38
  type SchemaFactory_base,
39
39
  } from "./schemaFactory.js";
40
40
  export { SchemaFactoryBeta, type SchemaStaticsBeta } from "./schemaFactoryBeta.js";
41
- export { SchemaFactoryAlpha } from "./schemaFactoryAlpha.js";
41
+ export {
42
+ SchemaFactoryAlpha,
43
+ type SchemaStaticsAlpha,
44
+ type NodeProvider,
45
+ } from "./schemaFactoryAlpha.js";
42
46
  export {
43
47
  eraseSchemaDetails,
44
48
  eraseSchemaDetailsSubclassable,
45
49
  } from "./eraseSchemaDetails.js";
50
+ export type {
51
+ ErasedSchema,
52
+ ErasedNode,
53
+ ErasedSchemaSubclassable,
54
+ } from "./eraseSchemaDetails.js";
46
55
  export type {
47
56
  ValidateRecursiveSchema,
48
57
  FixRecursiveArraySchema,
@@ -105,6 +114,8 @@ export type {
105
114
  AllowedTypesFullFromMixedUnsafe,
106
115
  UnannotateAllowedTypesListUnsafe,
107
116
  AnnotateAllowedTypesListUnsafe,
117
+ FieldHasDefaultAlphaUnsafe,
118
+ InsertableObjectFromSchemaRecordAlphaUnsafe,
108
119
  } from "./typesUnsafe.js";
109
120
 
110
121
  export {
@@ -403,7 +403,14 @@ export class SchemaFactory<
403
403
  > {
404
404
  return objectSchema(scoped(this, name), fields, true, {
405
405
  ...defaultSchemaFactoryObjectOptions,
406
- });
406
+ }) as TreeNodeSchemaClass<
407
+ ScopedSchemaName<TScope, Name>,
408
+ NodeKind.Object,
409
+ TreeObjectNode<T, ScopedSchemaName<TScope, Name>>,
410
+ object & InsertableObjectFromSchemaRecord<T>,
411
+ true,
412
+ T
413
+ >;
407
414
  }
408
415
 
409
416
  /**
@@ -4,20 +4,27 @@
4
4
  */
5
5
 
6
6
  import type { RestrictiveStringRecord } from "../../util/index.js";
7
- import type {
8
- NodeKind,
9
- TreeNodeSchemaClass,
10
- ImplicitAllowedTypes,
11
- WithType,
7
+ import {
8
+ type NodeKind,
9
+ type TreeNodeSchemaClass,
10
+ type ImplicitAllowedTypes,
11
+ type WithType,
12
+ normalizeAllowedTypes,
13
+ isTreeNode,
12
14
  } from "../core/index.js";
13
- import type { ImplicitFieldSchema } from "../fieldSchema.js";
14
15
  // These imports prevent a large number of type references in the API reports from showing up as *_2.
15
16
  /* eslint-disable unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars, import-x/no-duplicates */
16
- import type {
17
- FieldProps,
18
- FieldSchemaAlpha,
19
- FieldPropsAlpha,
20
- FieldKind,
17
+ import {
18
+ type FieldProps,
19
+ type FieldSchemaAlpha,
20
+ type FieldPropsAlpha,
21
+ type FieldKind,
22
+ type ImplicitFieldSchema,
23
+ type InsertableTreeFieldFromImplicitField,
24
+ type FieldSchema,
25
+ getDefaultProvider,
26
+ createFieldSchema,
27
+ type DefaultProvider,
21
28
  } from "../fieldSchema.js";
22
29
  import type { LeafSchema } from "../leafNodeSchema.js";
23
30
  import {
@@ -26,12 +33,14 @@ import {
26
33
  type MapNodeCustomizableSchema,
27
34
  mapSchema,
28
35
  type ObjectNodeSchema,
36
+ type ObjectNodeSchemaWorkaround,
29
37
  objectSchema,
30
38
  type RecordNodeCustomizableSchema,
31
39
  recordSchema,
32
40
  } from "../node-kinds/index.js";
33
41
  import type { SchemaType, SimpleObjectNodeSchema } from "../simpleSchema.js";
34
42
  import type { SimpleLeafNodeSchema } from "../simpleSchema.js";
43
+ import { unhydratedFlexTreeFromInsertableNode } from "../unhydratedFlexTreeFromInsertable.js";
35
44
 
36
45
  import {
37
46
  defaultSchemaFactoryObjectOptions,
@@ -42,15 +51,185 @@ import {
42
51
  } from "./schemaFactory.js";
43
52
  import { SchemaFactoryBeta } from "./schemaFactoryBeta.js";
44
53
  import { schemaStatics } from "./schemaStatics.js";
54
+ import { TreeBeta } from "./treeBeta.js";
45
55
  import type {
46
56
  ArrayNodeCustomizableSchemaUnsafe,
57
+ FieldSchemaAlphaUnsafe,
58
+ InsertableObjectFromSchemaRecordAlphaUnsafe,
47
59
  MapNodeCustomizableSchemaUnsafe,
48
60
  System_Unsafe,
49
61
  TreeRecordNodeUnsafe,
62
+ Unenforced,
50
63
  } from "./typesUnsafe.js";
51
- import type { FieldSchemaAlphaUnsafe } from "./typesUnsafe.js";
52
64
  /* eslint-enable unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars, import-x/no-duplicates */
53
65
 
66
+ /**
67
+ * A provider for values in tree nodes.
68
+ *
69
+ * @remarks
70
+ * This type represents two ways to provide node values:
71
+ *
72
+ * 1. **A value**: Provide any value directly (number, string, object, array, etc.). When a value is provided,
73
+ * the data is copied for each use to ensure independence between instances. The value must be of an allowed type for the field.
74
+ *
75
+ * 2. **A generator function**: A function that returns a value. The function is called each time a default is needed,
76
+ * allowing for dynamic defaults or explicit control over value creation. The return value must be of an allowed type for the field.
77
+ *
78
+ * Values should be preferred over generator functions when possible, as they are simpler and more efficient.
79
+ * Generator functions should be used when the default value needs to be dynamic or when it is not possible to provide a value directly.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * // Provide a value directly
84
+ * factory.withDefault(factory.required(factory.string), "default")
85
+ * factory.withDefault(factory.optional(Person), new Person({ name: "Guest" }))
86
+ *
87
+ * // Use a generator function
88
+ * factory.withDefault(factory.required(factory.string), () => crypto.randomUUID())
89
+ * factory.withDefault(factory.optional(Person), () => new Person({ name: "Guest" }))
90
+ * ```
91
+ *
92
+ * @alpha @sealed
93
+ */
94
+ export type NodeProvider<T> = T | (() => T);
95
+
96
+ /**
97
+ * Stateless APIs exposed via {@link SchemaFactoryBeta} as both instance properties and as statics.
98
+ * @see {@link SchemaStatics} for why this is useful.
99
+ * @system @sealed @alpha
100
+ */
101
+ export interface SchemaStaticsAlpha {
102
+ /**
103
+ * Creates a field schema with a default value. Fields with defaults (whether required or optional) are recognized by the type system as optional in constructors,
104
+ * allowing them to be omitted when creating new nodes.
105
+ *
106
+ * @param fieldSchema - The field schema to add a default to (e.g., `factory.required(factory.string)` or `factory.optional(factory.number)`)
107
+ * @param defaultValue - A {@link NodeProvider} specifying the default value.
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const MySchema = factory.objectAlpha("MyObject", {
112
+ * // Provide values directly
113
+ * name: factory.withDefault(factory.required(factory.string), "untitled"),
114
+ * count: factory.withDefault(factory.required(factory.number), 0),
115
+ * metadata: factory.withDefault(factory.optional(Metadata), new Metadata({ version: 1 })),
116
+ *
117
+ * // Use generator functions for dynamic values
118
+ * timestamp: factory.withDefault(factory.required(factory.number), () => Date.now()),
119
+ * id: factory.withDefault(factory.required(factory.string), () => crypto.randomUUID()),
120
+ * });
121
+ *
122
+ * const obj1 = new MySchema({}); // All defaults applied
123
+ * const obj2 = new MySchema({ name: "custom" }); // name="custom", other defaults applied
124
+ * ```
125
+ *
126
+ * @privateRemarks
127
+ * This function wraps an existing field schema and adds a default value provider to it.
128
+ * The default value will be used when constructing nodes if the field is not explicitly provided or set to `undefined`.
129
+ *
130
+ * Defaults are evaluated eagerly during node construction, unlike identifier defaults which require context.
131
+ */
132
+ readonly withDefault: <
133
+ Kind extends FieldKind,
134
+ Types extends ImplicitAllowedTypes,
135
+ TCustomMetadata = unknown,
136
+ >(
137
+ fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>,
138
+ defaultValue: NodeProvider<InsertableTreeFieldFromImplicitField<FieldSchema<Kind, Types>>>,
139
+ ) => FieldSchemaAlpha<
140
+ Kind,
141
+ Types,
142
+ TCustomMetadata,
143
+ FieldPropsAlpha<TCustomMetadata> & { defaultProvider: DefaultProvider }
144
+ >;
145
+ /**
146
+ * {@link SchemaStaticsAlpha.withDefault} except tweaked to work better for recursive types.
147
+ * Use with {@link ValidateRecursiveSchema} for improved type safety.
148
+ * @remarks
149
+ * This version of {@link SchemaStaticsAlpha.withDefault} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.
150
+ * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.
151
+ */
152
+ withDefaultRecursive: <
153
+ Kind extends FieldKind,
154
+ Types extends System_Unsafe.ImplicitAllowedTypesUnsafe,
155
+ TCustomMetadata = unknown,
156
+ >(
157
+ fieldSchema: System_Unsafe.FieldSchemaUnsafe<Kind, Types, TCustomMetadata>,
158
+ defaultValue: Unenforced<
159
+ NodeProvider<
160
+ System_Unsafe.InsertableTreeFieldFromImplicitFieldUnsafe<
161
+ System_Unsafe.FieldSchemaUnsafe<Kind, Types>
162
+ >
163
+ >
164
+ >,
165
+ ) => FieldSchemaAlphaUnsafe<
166
+ Kind,
167
+ Types,
168
+ TCustomMetadata,
169
+ FieldPropsAlpha<TCustomMetadata> & { defaultProvider: DefaultProvider }
170
+ >;
171
+ }
172
+
173
+ const withDefault = <
174
+ Kind extends FieldKind,
175
+ Types extends ImplicitAllowedTypes,
176
+ TCustomMetadata = unknown,
177
+ >(
178
+ fieldSchema: FieldSchema<Kind, Types, TCustomMetadata>,
179
+ defaultValue: NodeProvider<InsertableTreeFieldFromImplicitField<FieldSchema<Kind, Types>>>,
180
+ ): FieldSchemaAlpha<
181
+ Kind,
182
+ Types,
183
+ TCustomMetadata,
184
+ FieldPropsAlpha<TCustomMetadata> & { defaultProvider: DefaultProvider }
185
+ > => {
186
+ const typedFieldSchema = fieldSchema as FieldSchemaAlpha<Kind, Types, TCustomMetadata>;
187
+
188
+ // create the default provider function, it is called eagerly during node construction
189
+ const defaultProvider = getDefaultProvider(() => {
190
+ // Resolve the value: if it's a function, call it; otherwise use it directly
191
+ let insertableValue =
192
+ typeof defaultValue === "function" ? (defaultValue as () => unknown)() : defaultValue;
193
+
194
+ // If the value is an already-constructed TreeNode (e.g., from a generator function that
195
+ // returns the same instance repeatedly), clone it to ensure each use gets a fresh instance.
196
+ // This prevents multi-parenting errors.
197
+ if (isTreeNode(insertableValue)) {
198
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
+ insertableValue = TreeBeta.clone(insertableValue as any);
200
+ }
201
+
202
+ // For optional fields with an undefined default, return an empty array (no value).
203
+ if (insertableValue === undefined) {
204
+ return [];
205
+ }
206
+
207
+ // Convert the insertable value to an unhydrated flex tree.
208
+ // For insertable data, this creates a fresh tree structure.
209
+ const allowedTypeSet = normalizeAllowedTypes(typedFieldSchema.allowedTypes).evaluateSet();
210
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
211
+ return [unhydratedFlexTreeFromInsertableNode(insertableValue as any, allowedTypeSet)];
212
+ });
213
+
214
+ // create a new field schema with the default provider
215
+ const propsWithDefault = {
216
+ ...typedFieldSchema.props,
217
+ defaultProvider,
218
+ };
219
+
220
+ return createFieldSchema(
221
+ typedFieldSchema.kind,
222
+ typedFieldSchema.allowedTypes,
223
+ propsWithDefault,
224
+ );
225
+ };
226
+
227
+ const schemaStaticsAlpha: SchemaStaticsAlpha = {
228
+ withDefault,
229
+
230
+ withDefaultRecursive: withDefault as SchemaStaticsAlpha["withDefaultRecursive"],
231
+ };
232
+
54
233
  /**
55
234
  * {@link SchemaFactory} with additional alpha APIs.
56
235
  *
@@ -79,19 +258,7 @@ export class SchemaFactoryAlpha<
79
258
  name: Name,
80
259
  fields: T,
81
260
  options?: ObjectSchemaOptionsAlpha<TCustomMetadata>,
82
- ): ObjectNodeSchema<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata> & {
83
- /**
84
- * Typing checking workaround: not for for actual use.
85
- * @remarks
86
- * This API collides with {@link TreeNodeSchemaCore.createFromInsertable} to disable a type checking optimization which produces different and undesired results.
87
- * See {@link https://github.com/microsoft/TypeScript/issues/59049#issuecomment-2773459693} for more details.
88
- * @privateRemarks
89
- * The specific issue here is non-empty POJO mode object schema not being assignable to `ObjectNodeSchema`,
90
- * See the above link and the tests in objectNode.spec.ts which reference it.
91
- * @system
92
- */
93
- readonly createFromInsertable: unknown;
94
- } {
261
+ ): ObjectNodeSchemaWorkaround<ScopedSchemaName<TScope, Name>, T, true, TCustomMetadata> {
95
262
  return objectSchema(scoped<TScope, TName, Name>(this, name), fields, true, {
96
263
  ...defaultSchemaFactoryObjectOptions,
97
264
  ...options,
@@ -154,6 +321,56 @@ export class SchemaFactoryAlpha<
154
321
  >;
155
322
  }
156
323
 
324
+ /**
325
+ * Alpha version of {@link SchemaFactory.objectRecursive} that supports field defaults via {@link SchemaStaticsAlpha.withDefaultRecursive}.
326
+ * Use with {@link ValidateRecursiveSchema} for improved type safety.
327
+ * @remarks
328
+ * Use this instead of {@link SchemaFactory.objectRecursive} when fields use {@link SchemaStaticsAlpha.withDefaultRecursive}.
329
+ * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.
330
+ */
331
+ public objectRecursiveAlpha<
332
+ const Name extends TName,
333
+ const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>,
334
+ const TCustomMetadata = unknown,
335
+ >(
336
+ name: Name,
337
+ t: T,
338
+ options?: ObjectSchemaOptionsAlpha<TCustomMetadata>,
339
+ ): TreeNodeSchemaClass<
340
+ ScopedSchemaName<TScope, Name>,
341
+ NodeKind.Object,
342
+ System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>,
343
+ object & InsertableObjectFromSchemaRecordAlphaUnsafe<T>,
344
+ false,
345
+ T,
346
+ never,
347
+ TCustomMetadata
348
+ > &
349
+ SimpleObjectNodeSchema<SchemaType.View, TCustomMetadata> &
350
+ Pick<ObjectNodeSchema, "fields"> {
351
+ type TScopedName = ScopedSchemaName<TScope, Name>;
352
+ return this.objectAlpha(
353
+ name,
354
+ t as T & RestrictiveStringRecord<ImplicitFieldSchema>,
355
+ options,
356
+ ) as unknown as TreeNodeSchemaClass<
357
+ TScopedName,
358
+ NodeKind.Object,
359
+ System_Unsafe.TreeObjectNodeUnsafe<T, TScopedName>,
360
+ object & InsertableObjectFromSchemaRecordAlphaUnsafe<T>,
361
+ false,
362
+ T,
363
+ never,
364
+ TCustomMetadata
365
+ > &
366
+ ObjectNodeSchema<
367
+ ScopedSchemaName<TScope, Name>,
368
+ RestrictiveStringRecord<ImplicitFieldSchema>,
369
+ false,
370
+ TCustomMetadata
371
+ >;
372
+ }
373
+
157
374
  /**
158
375
  * {@inheritDoc SchemaStatics.leaves}
159
376
  */
@@ -209,6 +426,26 @@ export class SchemaFactoryAlpha<
209
426
  */
210
427
  public override readonly requiredRecursive = schemaStatics.requiredRecursive;
211
428
 
429
+ /**
430
+ * {@inheritdoc SchemaStaticsAlpha.withDefault}
431
+ */
432
+ public readonly withDefault = schemaStaticsAlpha.withDefault;
433
+
434
+ /**
435
+ * {@inheritdoc SchemaStaticsAlpha.withDefault}
436
+ */
437
+ public static readonly withDefault = schemaStaticsAlpha.withDefault;
438
+
439
+ /**
440
+ * {@inheritdoc SchemaStaticsAlpha.withDefault}
441
+ */
442
+ public readonly withDefaultRecursive = schemaStaticsAlpha.withDefaultRecursive;
443
+
444
+ /**
445
+ * {@inheritdoc SchemaStaticsAlpha.withDefault}
446
+ */
447
+ public static readonly withDefaultRecursive = schemaStaticsAlpha.withDefaultRecursive;
448
+
212
449
  /**
213
450
  * Define a {@link TreeNodeSchema} for a {@link TreeMapNode}.
214
451
  *