@@ -59,7 +59,15 @@ export const noChangeHandler: FieldChangeHandler<0> = {
5959 getCrossFieldKeys : ( ) => [ ] ,
6060} ;
6161
62- export interface ValueFieldEditor extends FieldEditor < OptionalChangeset > {
62+ /**
63+ * {@link FieldEditor } for required fields (always contain exactly 1 child).
64+ * @remarks
65+ * This shares code with optional fields, since they are the same edit wise except setting to empty is not allowed,
66+ * and the content is always assumed to not be empty.
67+ * This means the actual edits implemented for optional fields are sufficient to support required fields
68+ * which is why this is defined and implemented in terms of optional fields.
69+ */
70+ export interface RequiredFieldEditor extends FieldEditor < OptionalChangeset > {
6371 /**
6472 * Creates a change which replaces the current value of the field with `newValue`.
6573 * @param ids - The ids for the fill and detach fields.
@@ -68,42 +76,41 @@ export interface ValueFieldEditor extends FieldEditor<OptionalChangeset> {
6876}
6977
7078const optionalIdentifier = brandConst ( "Optional" ) < FieldKindIdentifier > ( ) ;
79+
7180/**
7281 * 0 or 1 items.
7382 */
74- export const optional = new FlexFieldKind (
75- optionalIdentifier ,
76- Multiplicity . Optional ,
77- optionalChangeHandler ,
78- ( types , other ) =>
83+ export const optional = new FlexFieldKind ( optionalIdentifier , Multiplicity . Optional , {
84+ changeHandler : optionalChangeHandler ,
85+ allowsTreeSupersetOf : ( types , other ) =>
7986 ( other . kind === sequence . identifier || other . kind === optionalIdentifier ) &&
8087 allowsTreeSchemaIdentifierSuperset ( types , other . types ) ,
81- new Set ( [ ] ) ,
82- ) ;
88+ } ) ;
8389
84- export const valueFieldEditor : ValueFieldEditor = {
90+ export const requiredFieldEditor : RequiredFieldEditor = {
8591 ...optionalFieldEditor ,
8692 set : ( ids : {
8793 fill : ChangeAtomId ;
8894 detach : ChangeAtomId ;
8995 } ) : OptionalChangeset => optionalFieldEditor . set ( false , ids ) ,
9096} ;
9197
92- export const valueChangeHandler : FieldChangeHandler < OptionalChangeset , ValueFieldEditor > = {
93- ...optional . changeHandler ,
94- editor : valueFieldEditor ,
98+ export const requiredFieldChangeHandler : FieldChangeHandler <
99+ OptionalChangeset ,
100+ RequiredFieldEditor
101+ > = {
102+ ...optionalChangeHandler ,
103+ editor : requiredFieldEditor ,
95104} ;
96105
97106const requiredIdentifier = brandConst ( "Value" ) < FieldKindIdentifier > ( ) ;
98107
99108/**
100109 * Exactly one item.
101110 */
102- export const required = new FlexFieldKind (
103- requiredIdentifier ,
104- Multiplicity . Single ,
105- valueChangeHandler ,
106- ( types , other ) =>
111+ export const required = new FlexFieldKind ( requiredIdentifier , Multiplicity . Single , {
112+ changeHandler : requiredFieldChangeHandler ,
113+ allowsTreeSupersetOf : ( types , other ) =>
107114 // By omitting Identifier here,
108115 // this is making a policy choice that a schema upgrade cannot be done from required to identifier.
109116 // Since an identifier can be upgraded into a required field,
@@ -113,43 +120,35 @@ export const required = new FlexFieldKind(
113120 other . kind === requiredIdentifier ||
114121 other . kind === optional . identifier ) &&
115122 allowsTreeSchemaIdentifierSuperset ( types , other . types ) ,
116- new Set ( ) ,
117- ) ;
123+ } ) ;
118124
119125const sequenceIdentifier = brandConst ( "Sequence" ) < FieldKindIdentifier > ( ) ;
120126
121127/**
122128 * 0 or more items.
123129 */
124- export const sequence = new FlexFieldKind (
125- sequenceIdentifier ,
126- Multiplicity . Sequence ,
127- sequenceFieldChangeHandler ,
128- ( types , other ) =>
130+ export const sequence = new FlexFieldKind ( sequenceIdentifier , Multiplicity . Sequence , {
131+ changeHandler : sequenceFieldChangeHandler ,
132+ allowsTreeSupersetOf : ( types , other ) =>
129133 other . kind === sequenceIdentifier &&
130134 allowsTreeSchemaIdentifierSuperset ( types , other . types ) ,
131- // TODO: add normalizer/importers for handling ops from other kinds.
132- new Set ( [ ] ) ,
133- ) ;
135+ } ) ;
134136
135137const identifierFieldIdentifier = brandConst ( "Identifier" ) < FieldKindIdentifier > ( ) ;
136138
137139/**
138140 * Exactly one identifier.
139141 */
140- export const identifier = new FlexFieldKind (
141- identifierFieldIdentifier ,
142- Multiplicity . Single ,
143- noChangeHandler ,
144- ( types , other ) =>
142+ export const identifier = new FlexFieldKind ( identifierFieldIdentifier , Multiplicity . Single , {
143+ changeHandler : noChangeHandler ,
144+ allowsTreeSupersetOf : ( types , other ) =>
145145 // Allows upgrading from identifier to required: which way this upgrade is allowed to go is a subjective policy choice.
146146 ( other . kind === sequence . identifier ||
147147 other . kind === requiredIdentifier ||
148148 other . kind === optional . identifier ||
149149 other . kind === identifierFieldIdentifier ) &&
150150 allowsTreeSchemaIdentifierSuperset ( types , other . types ) ,
151- new Set ( ) ,
152- ) ;
151+ } ) ;
153152
154153/**
155154 * Exactly 0 items.
@@ -182,10 +181,12 @@ export const identifier = new FlexFieldKind(
182181export const forbidden = new FlexFieldKind (
183182 forbiddenFieldKindIdentifier ,
184183 Multiplicity . Forbidden ,
185- noChangeHandler ,
186- // All multiplicities other than Value support empty.
187- ( types , other ) => fieldKinds . get ( other . kind ) ?. multiplicity !== Multiplicity . Single ,
188- new Set ( ) ,
184+ {
185+ changeHandler : noChangeHandler ,
186+ // All multiplicities other than Value support empty.
187+ allowsTreeSupersetOf : ( types , other ) =>
188+ fieldKinds . get ( other . kind ) ?. multiplicity !== Multiplicity . Single ,
189+ } ,
189190) ;
190191
191192export const fieldKindConfigurations : ReadonlyMap <
@@ -270,15 +271,31 @@ export const fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind> = new M
270271// TODO: ensure thy work in generated docs.
271272// TODO: add these comments to the rest of the cases below.
272273export interface Required
273- extends FlexFieldKind < ValueFieldEditor , "Value" , Multiplicity . Single > { }
274+ extends FlexFieldKind < RequiredFieldEditor , typeof requiredIdentifier , Multiplicity . Single > { }
274275export interface Optional
275- extends FlexFieldKind < OptionalFieldEditor , "Optional" , Multiplicity . Optional > { }
276+ extends FlexFieldKind <
277+ OptionalFieldEditor ,
278+ typeof optionalIdentifier ,
279+ Multiplicity . Optional
280+ > { }
276281export interface Sequence
277- extends FlexFieldKind < SequenceFieldEditor , "Sequence" , Multiplicity . Sequence > { }
282+ extends FlexFieldKind <
283+ SequenceFieldEditor ,
284+ typeof sequenceIdentifier ,
285+ Multiplicity . Sequence
286+ > { }
278287export interface Identifier
279- extends FlexFieldKind < FieldEditor < 0 > , "Identifier" , Multiplicity . Single > { }
288+ extends FlexFieldKind <
289+ FieldEditor < 0 > ,
290+ typeof identifierFieldIdentifier ,
291+ Multiplicity . Single
292+ > { }
280293export interface Forbidden
281- extends FlexFieldKind < FieldEditor < 0 > , "Forbidden" , Multiplicity . Forbidden > { }
294+ extends FlexFieldKind <
295+ FieldEditor < 0 > ,
296+ typeof forbiddenFieldKindIdentifier ,
297+ Multiplicity . Forbidden
298+ > { }
282299
283300/**
284301 * Default FieldKinds with their editor types erased.
0 commit comments