@dynamicforms/vue-forms 2.0.2 → 3.0.0-alpha.1

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.
package/dist/index.d.ts CHANGED
@@ -1,38 +1,32 @@
1
- import { ComponentOptionsMixin } from 'vue';
2
- import { ComponentProvideOptions } from 'vue';
3
- import { ComputedRef } from 'vue';
4
- import { DefineComponent } from 'vue';
5
- import { PublicProps } from 'vue';
6
1
  import { Ref } from 'vue';
7
- import { TranslateStringsCallback } from '@dynamicforms/translatable';
8
2
 
9
3
  /**
10
- * Thrown from a handler to end the run it is in. What the trigger answers with is the exception itself rather than
11
- * `null`, so a caller can tell a run a handler ended from one that reached no handler at all - and the setters
12
- * that ask a `*Changing*` handler read it as a refusal and write nothing. The answer carries it directly where the
13
- * chain ran synchronously, and as what the answered promise resolves to where a handler in it was asynchronous.
4
+ * Thrown from a handler to end the current run. The trigger returns the exception itself, not `null`, so a caller
5
+ * can distinguish a run a handler ended from one that reached no handler; a setter that triggers a `*Changing*`
6
+ * handler cancels the write when it receives it. The trigger returns the exception directly if the chain ran
7
+ * synchronously, and as the resolution of the returned promise if a handler in it was asynchronous.
14
8
  */
15
9
  export declare class AbortEventHandlingException extends Error {
16
10
  }
17
11
 
18
12
  /**
19
13
  * What a form element accepts and what it sends. The four values follow HTML: `'editable'` and `'readonly'` send
20
- * the element's value the way an `<input>` and an `<input readonly>` are submitted, `'disabled'` sends nothing the
21
- * way an `<input disabled>` is left out, and `'disabled-null'` sends `null` in the element's place.
14
+ * the element's value, as an `<input>` and an `<input readonly>` are submitted, `'disabled'` sends nothing, as an
15
+ * `<input disabled>` is omitted, and `'disabled-null'` sends `null` in place of the element's value.
22
16
  *
23
- * | access | accepts input | contributes to its container's `value` |
17
+ * | access | accepts input | sends to its container's `value` |
24
18
  * |-------------------|---------------|----------------------------------------|
25
19
  * | `'editable'` | yes | its value |
26
20
  * | `'readonly'` | no | its value |
27
21
  * | `'disabled'` | no | nothing: the key or row is left out |
28
22
  * | `'disabled-null'` | no | `null` |
29
23
  *
30
- * An element that contributes no value of its own is not counted in its container's validity. `fullValue` carries
31
- * every element whatever its access.
24
+ * An element that sends nothing is not counted in its container's validity. `fullValue` contains every element
25
+ * whatever its access.
32
26
  */
33
27
  export declare type Access = 'editable' | 'readonly' | 'disabled' | 'disabled-null';
34
28
 
35
- /** Told once an element's `access` has been written. */
29
+ /** Fires after an element's `access` has been written. */
36
30
  export declare class AccessChangedAction extends FieldActionBase {
37
31
  constructor(executorFn: (field: FieldBase, supr: FieldActionExecute, newValue: Access, oldValue: Access) => void);
38
32
  static get classIdentifier(): symbol;
@@ -40,8 +34,8 @@ export declare class AccessChangedAction extends FieldActionBase {
40
34
  }
41
35
 
42
36
  /**
43
- * Asked before an element's `access` is written. A handler answers with the access to write instead, or throws
44
- * `AbortEventHandlingException` to refuse the write.
37
+ * Fires before an element's `access` is written. A handler returns the access to write instead, or throws
38
+ * `AbortEventHandlingException` to cancel the write.
45
39
  */
46
40
  export declare class AccessChangingAction extends FieldActionBase {
47
41
  constructor(executorFn: (field: FieldBase, supr: FieldActionExecute, newValue: Access, oldValue: Access) => Access);
@@ -56,37 +50,56 @@ export declare class Action<T extends ActionValue = ActionValue, X extends objec
56
50
  get [Symbol.toStringTag](): string;
57
51
  protected init(params?: IFieldParams<T, X>): void;
58
52
  /**
59
- * A copy of the value this action holds, carrying one member rewritten. A member handed undefined is dropped
60
- * from the copy rather than written into it: an own key holding undefined is invisible to a reader and to
61
- * JSON, but lodash isEqual compares own-key sets, so writing one would leave the action permanently changed
62
- * against a baseline that never carried the key.
53
+ * Returns a copy of the value this action holds with one member replaced. A member set to undefined is deleted
54
+ * from the copy: an own key holding undefined is invisible to a reader and to JSON, but lodash isEqual compares
55
+ * own-key sets, so the action would remain changed against a baseline without that key.
63
56
  */
64
57
  private valueWith;
65
58
  get icon(): T['icon'];
66
59
  set icon(newValue: T['icon']);
67
60
  get label(): T['label'];
68
61
  /**
69
- * The two setters hand the value setter a new object rather than writing into the one the action holds, so each
70
- * is an ordinary value change: the handlers fire and isChanged answers over it.
71
- * The new object is built only for a member that differs from the one held - the value setter compares by
72
- * identity and every copy is a new object, so without the comparison here a write of the value already held
73
- * would announce a change and invalidate the value cache of every container above.
62
+ * The two setters pass a new object to the value setter instead of modifying the one the action holds, so each
63
+ * is a regular value change: the handlers fire and isChanged reflects it.
64
+ * The new object is built only if the member differs from the current one: the value setter compares by identity
65
+ * and every copy is a new object, so without this check a write of the current value would announce a change and
66
+ * invalidate the value cache of every container above.
74
67
  */
75
68
  set label(newValue: T['label']);
76
- /** the counter behind `busy`, allocated for this action the first time it is asked for */
69
+ /** `value.defaultConfirm`: whether a container's `confirm()` executes this action. */
70
+ get defaultConfirm(): boolean;
71
+ /** `value.defaultReject`: whether a container's `reject()` executes this action. */
72
+ get defaultReject(): boolean;
73
+ /**
74
+ * An action is a command, not data: it sends nothing to its container's `value` or `fullValue`, so it is not in
75
+ * the payload, does not affect the container's `isChanged`, and is not counted in its validity. Its validators do
76
+ * not run, as on any element that sends nothing.
77
+ */
78
+ protected serializesAs(): 'value' | 'null' | 'omit';
79
+ /** An action is sent nowhere, so a validator registered on it reaches no result and adds no error. */
80
+ [SentNowhere](): boolean;
81
+ /**
82
+ * Whether the action can run now: it accepts input (`effectiveEnabled`), is shown (`visibility` is `'full'`), is
83
+ * not running (`busy` is false), and every `ExecuteAction` handler registered on it returns true from
84
+ * `canExecute()`. Reactive, so a button binds `:disabled="!action.executable"`. A container's `confirm()` and
85
+ * `reject()` execute only an executable action. `execute()` does not check it.
86
+ */
87
+ get executable(): boolean;
88
+ /** The `ExecuteAction` handlers registered on this action, in registration order. */
89
+ [ExecuteHandlers](): ExecuteAction[];
90
+ /** the counter behind `busy`, created on first access */
77
91
  private get busyRuns();
78
- /** true from the moment execute() is called until the handler it ran has settled, however it settles */
92
+ /** true from the call to execute() until the handler it ran has settled, resolved or rejected */
79
93
  get busy(): boolean;
80
94
  /**
81
- * Runs the ExecuteAction chain registered on this action and answers what the chain returned. `busy` stands for
82
- * the length of the run: the chain is entered synchronously, and the flag is cleared once the value it produced
83
- * has settled - a handler that returns a promise holds it for as long as that promise takes, and one that
84
- * rejects clears it as it rejects.
95
+ * Runs the ExecuteAction chain registered on this action and returns the chain's result. `busy` is true for the
96
+ * duration of the run: the chain starts synchronously, and the flag is cleared when its result has settled; a
97
+ * handler that returns a promise keeps it set until that promise settles, and a rejection clears it.
85
98
  *
86
- * The answer is a promise whatever the handler returns, so a handler that throws rejects it rather than throwing
87
- * out of this call: a caller that does not await the answer and does not attach a catch handler leaves that
88
- * rejection unhandled. An `AbortEventHandlingException` is the one exception that does not reject: the answer
89
- * resolves with it, in a synchronous chain as in an asynchronous one.
99
+ * The return value is a promise whatever the handler returns, so a handler that throws rejects the promise; this
100
+ * call does not throw. A caller that neither awaits it nor attaches a catch handler leaves the rejection
101
+ * unhandled. An `AbortEventHandlingException` does not reject: the promise resolves with it, for a synchronous
102
+ * and an asynchronous chain alike.
90
103
  */
91
104
  execute(params?: any): Promise<any>;
92
105
  }
@@ -95,146 +108,168 @@ declare type ActionExecutor = (field: FieldBase, supr: FieldActionExecute, ...pa
95
108
 
96
109
  /**
97
110
  * The actions one declaration has registered, in registration order. A trigger walks them from the end backwards
98
- * and passes over the ones registered under another identifier, so the newest registration of an identifier is its
99
- * outermost handler and reaches the ones before it through the `supr` it is handed. A handler that does not call
100
- * `supr` ends the run there, and one that calls it may transform what it answers with.
111
+ * and skips the ones registered under another identifier, so the newest registration of an identifier is its
112
+ * outermost handler and calls the earlier ones through its `supr` argument. A handler that does not call `supr`
113
+ * ends the run, and one that calls it may transform the result.
101
114
  *
102
- * The order is the whole index. An element carries a handful of actions, and a walk over that many is cheaper than
103
- * a keyed lookup as well as smaller: measured over three actions, the walk is about twice as fast as `Map.get` and
104
- * the two maps it replaces cost about 500 bytes per declaration.
115
+ * The array is the only index. An element has few actions, and a linear walk over a few entries is faster and
116
+ * smaller than a keyed lookup.
105
117
  */
106
118
  export declare class ActionsMap {
107
119
  /**
108
- * Every action registered here, in registration order. It is replaced rather than written when an action is
109
- * dropped, so a run already walking it finishes on the array it started with and the removal takes effect from
110
- * the next trigger.
120
+ * Every action registered here, in registration order. Unregistering replaces the array instead of modifying it,
121
+ * so a run in progress finishes on the array it started with and the removal takes effect from the next trigger.
111
122
  */
112
123
  private actions;
113
124
  /**
114
- * Registers `action`. It becomes the outermost handler of its identifier, or - where `before` is given and is
115
- * registered here under the same identifier - takes that action's place in the order, so `before` wraps it and
116
- * reaches it through `supr`. That is what lets an action be added to a chain someone else built and still sit
117
- * inside a handler already there.
125
+ * Registers `action`. It becomes the outermost handler of its identifier, or, if `before` is given, is inserted
126
+ * at the position of `before`, so `before` wraps it and calls it through `supr`. This adds an action to an
127
+ * existing chain inside a handler that is already registered. Throws if `before` is not registered here under the
128
+ * same identifier, and a TypeError for an `ErrorPolicy` naming an origin another one registered here names.
118
129
  */
119
130
  register(action: FieldActionBase, before?: FieldActionBase): void;
120
- /** Drops `action` and answers whether it was registered here. */
131
+ /** Unregisters `action` and returns whether it was registered here. */
121
132
  unregister(action: FieldActionBase): boolean;
122
- /** True where something is registered under `identifier`. */
133
+ /** True if any action is registered under `identifier`. */
123
134
  willTrigger(identifier: symbol): boolean;
124
- /** True where any eager action is registered, whatever identifier it stands under. */
135
+ /** True if any eager action is registered, under any identifier. */
125
136
  get hasEager(): boolean;
126
- /** Runs the actions registered under `ActionClass` and answers with what the outermost of them returned. */
137
+ /** Runs the actions registered under `ActionClass` and returns the result of the outermost one. */
127
138
  trigger<T extends FieldActionBase>(ActionClass: (abstract new (...args: any[]) => T) & {
128
139
  classIdentifier: symbol;
129
140
  }, field: FieldBase, ...params: any[]): any;
130
141
  /**
131
- * Runs the eager actions of every identifier, each group on its own. A group is entered at its outermost eager
132
- * action, which is the last one registered under that identifier.
142
+ * Runs the eager actions of every identifier, each identifier's group separately. A group starts at its outermost
143
+ * eager action, the last one registered under that identifier. The rules run before the validators: a rule can
144
+ * change the element's access or value, so after one ran the validators receive what the element sends then, in
145
+ * place of the first parameter.
133
146
  */
134
147
  triggerEager(field: FieldBase, ...params: any[]): void;
135
- /** Runs the eager actions registered under `identifier` and nothing else. */
148
+ /**
149
+ * Runs the eager actions other than the validators, as `triggerEager` does: the rules that set an element's flags
150
+ * or values from its record.
151
+ */
152
+ triggerEagerRules(field: FieldBase, ...params: any[]): void;
153
+ /** Runs the eager groups whose actions `include` accepts; returns whether any ran. */
154
+ private runEager;
155
+ /** Runs only the eager actions registered under `identifier`. */
136
156
  triggerEagerFor(identifier: symbol, field: FieldBase, ...params: any[]): any;
137
- /** the validators registered here, in registration order */
157
+ /** The registered actions with `identifier`, in registration order. */
158
+ ofClass(identifier: symbol): FieldActionBase[];
159
+ /** The validators registered here, in registration order. */
138
160
  get validators(): Validator[];
139
161
  /**
140
- * Tells every action here that it serves `owner`. A binding reads the map its declaration holds, so this is what
141
- * announces the new element to the actions already in it - the way registering an action announces the elements
142
- * it comes to serve.
162
+ * Binds every action in this map to `owner`. A binding uses its declaration's map, so this notifies the actions
163
+ * already in it of the new element, as registering an action binds it to the existing elements.
143
164
  */
144
165
  bindTo(owner: FieldBase): void;
145
- /** True where no eager action of `identifier` stands after `index`, which makes `index` the group's entry. */
166
+ /** Tells every action in this map that `owner` is reset to a new binding of its declaration. */
167
+ resetBinding(owner: FieldBase): void;
168
+ /** True if no eager action of the same identifier follows `index`, so `index` is the group's entry point. */
146
169
  private static outermostEager;
147
170
  /**
148
- * True where `value` is a promise, which is what a walk through an asynchronous handler answers with. The test is
149
- * the type rather than a `then` member: a handler may answer with a value object that carries one, and calling
150
- * `then` on such an object replaces the answer with whatever that call returns.
171
+ * True if `value` is a promise, which a walk through an asynchronous handler returns. The test checks the type,
172
+ * not a `then` member: a handler may return a value object with a `then` member, and calling it would replace the
173
+ * result with that call's return value.
151
174
  */
152
175
  private static isPromise;
153
176
  /**
154
- * Answers an abort with itself on the asynchronous path as well. Where a handler in the chain is asynchronous, the
155
- * walk answers with a promise and the abort raised under it arrives as that promise's rejection; this turns it back
156
- * into the value the caller receives, so a promise the trigger answers with resolves to the exception instead of
157
- * rejecting with it. Anything else keeps rejecting.
177
+ * Returns an abort as a value on the asynchronous path as well. If a handler in the chain is asynchronous, the
178
+ * walk returns a promise and an abort arrives as its rejection; this converts it to a resolution, so the promise
179
+ * the trigger returns resolves to the exception. Any other rejection is passed on.
158
180
  */
159
181
  private static answerAbort;
160
182
  /**
161
- * Enters a group at its outermost action. An abort ends the run and is answered with rather than raised: the
162
- * exception is what the caller receives - directly where the chain ran synchronously, as what the answered promise
163
- * resolves to where it did not - so a run a handler ended is told apart from one that reached no handler and from
164
- * one whose handler answered null.
183
+ * Runs a group from its outermost action. An abort ends the run and is returned, not thrown: the caller receives
184
+ * the exception directly if the chain ran synchronously, and as the resolution of the returned promise otherwise.
185
+ * This distinguishes an aborted run from one that reached no handler and from one whose handler returned null.
165
186
  */
166
187
  private run;
167
188
  /**
168
- * Walks from `index` backwards to the first action of `identifier`, handing it a `supr` that continues at the one
169
- * before it. The actions registered under other identifiers are passed over, so the array needs no grouping of
170
- * its own; the closures exist for the length of the run and only as deep as the run actually goes.
189
+ * Walks from `index` backwards to the first action of `identifier` and calls it with a `supr` that continues at
190
+ * the action before it. Actions registered under other identifiers are skipped, so the array needs no grouping;
191
+ * a closure is created only for each level the run reaches and lives only for the run.
171
192
  */
172
193
  private walk;
173
194
  }
174
195
 
175
196
  /**
176
- * The value an `Action` holds. Both members are `unknown` because `Action` states the concept and a UI library
177
- * states what it renders: a subclass declares its value type with `label` and `icon` in whatever shape it renders
178
- * them - `string | MdString`, a per-breakpoint object - and the accessors below answer at that type, because they
179
- * read it off `T` rather than fixing one of their own.
197
+ * The value an `Action` holds. Both members are `unknown` because `Action` defines the concept and a UI library
198
+ * defines what it renders: a subclass declares its value type with `label` and `icon` in the shape it renders them
199
+ * (a string, a markdown string, a per-breakpoint object), and the accessors below return that type, because they
200
+ * read it from `T`.
180
201
  *
181
- * The consequence for an `Action` built without a type argument is that reading either member answers `unknown`
182
- * and the reader states what it expects. That is the shape the class is for; an application that renders actions
183
- * uses the subclass its UI library ships.
202
+ * For an `Action` built without a type argument, both members are `unknown` and the reader casts them. An
203
+ * application that renders actions uses the subclass its UI library provides.
184
204
  */
185
205
  export declare interface ActionValue {
186
206
  label?: unknown;
187
207
  icon?: unknown;
208
+ /** The action a container's `confirm()` executes: the one a confirm gesture, such as Enter, triggers. */
209
+ defaultConfirm?: boolean;
210
+ /** The action a container's `reject()` executes: the one a reject gesture, such as Escape, triggers. */
211
+ defaultReject?: boolean;
188
212
  }
189
213
 
190
214
  /**
191
- * The values a field may hold: a fixed list, or a reference or a callback for a list that is filled in or replaced
192
- * after the validator is built - the options a server answers with, or the ones another field's value leaves open.
215
+ * The values a field may hold: a fixed list, or a ref or a callback for a list that is filled or replaced after
216
+ * the validator is built (options returned by a server, or the options another field's value allows).
193
217
  */
194
218
  declare type AllowedValues<T> = T[] | Ref<T[]> | (() => T[]);
195
219
 
196
220
  /**
197
- * Depending on the useMarkdownInValidators setting, return either markdown or a plain string error message. A
198
- * Ref is stripped/wrapped on read rather than once here, so a translated template re-applies the same choice
199
- * as its text changes.
200
- * @param mdErrorString markdown source to optionally be stripped
201
- * @return MdString or string, or a ComputedRef of either where `mdErrorString` is itself a Ref
221
+ * Key of the `FieldBase` method that starts counting one asynchronous validation run and returns the function that
222
+ * ends it. A validator calls it; the package does not export it.
202
223
  */
203
- export declare function buildErrorMessage<T extends string | Ref<string>>(mdErrorString: T): T extends Ref<string> ? ComputedRef<string | MdString> : string | MdString;
224
+ declare const BeginValidating: unique symbol;
204
225
 
205
- export declare type ClassType = string | string[] | Record<string, boolean>;
226
+ /**
227
+ * The method a `Field` implements for `PluginContext.changeInPlace`. It is keyed by a symbol the package does not
228
+ * export, so it is not part of the documented API of `Field`.
229
+ */
230
+ declare const ChangeInPlace: unique symbol;
206
231
 
207
- export declare type ClassTypes = ClassType | ClassType[];
232
+ /**
233
+ * The base of the exceptions a `TargetedExecuteAction` ends with when its command did not complete. `execute()`
234
+ * resolves with it. A `SubmitAction` ends with a `SubmitFailedException` or a `SubmitRefusedException`, so the
235
+ * resolved value of a submit is `SubmitResult | CommandException`.
236
+ */
237
+ export declare abstract class CommandException extends AbortEventHandlingException {
238
+ }
239
+
240
+ /**
241
+ * The element a `SubmitAction` or a `RejectAction` works on: an element, or a callback that returns it for the
242
+ * action the handler is registered on.
243
+ */
244
+ export declare type CommandTarget = FieldBase | ((action: FieldBase) => FieldBase | null | undefined);
208
245
 
209
246
  declare class CompareTo<T = any> extends Validator {
210
247
  private isValidComparison;
211
248
  private readonly otherField;
212
249
  /**
213
- * The fields this validator is registered on. Registration reaches one element at a time - the rows of a list
214
- * take the validator on one by one, as they are built from the item template that carries it - so this is what
215
- * says which of the fields a declaration stands for actually carry the rule, and a field that never took it on
216
- * is left alone by a change of the compared field.
250
+ * The fields this validator is registered on. Registration happens one element at a time (the rows of a list
251
+ * receive the validator one by one, as they are built from the item template), so this set determines which
252
+ * elements of a declaration have the rule; a change of the compared element does not revalidate the others.
217
253
  */
218
254
  private readonly registrations;
219
255
  /**
220
- * The fields this validator has installed its listener on. A binding of such a field carries the listener too -
221
- * a binding takes on the actions of the field it was bound from - so the field it was bound from is what is
222
- * asked about as well, and a list of a thousand rows installs one listener rather than a thousand.
256
+ * The elements this validator has installed its listener on. A binding of such an element has the listener too
257
+ * (a binding uses the actions of its declaration), so the declaration is checked as well, and a list of N rows
258
+ * installs one listener, not N.
223
259
  */
224
260
  private readonly listening;
225
261
  /**
226
- * What the fields this validator was registered on were declared as. One entry stands for every binding of such a
227
- * field, so a change of a compared field finds the fields of the record that change happened in without a list
228
- * of a thousand rows being held here.
262
+ * The declarations of the fields this validator was registered on. One entry covers every binding of such a
263
+ * field, so a change of a compared element finds the fields of its record without this set holding every row.
229
264
  */
230
265
  private readonly declarations;
231
- constructor(otherField: CompareToTarget, isValidComparison: (myValue: T, otherValue: T) => boolean, message: RenderContentRef);
232
- /** The field `field` is compared against, within the record `field` belongs to. */
266
+ constructor(otherField: CompareToTarget, isValidComparison: (myValue: T, otherValue: T) => boolean, options?: ValidationErrorOptions);
267
+ /** The element `field` is compared against, within the record `field` belongs to. */
233
268
  private resolve;
234
269
  /**
235
- * Makes a change of `other` re-run this comparison. The listener re-runs it over the fields of the record the
236
- * change happened in rather than over the field that installed it, so the listener a row inherits with the field
237
- * it was bound from serves that row; and it re-runs this one validator, not the chain around it.
270
+ * Registers a listener so a change of `other` re-runs this comparison. The listener re-runs it over the fields of
271
+ * the record the change happened in, not over the field that installed it, so a listener a row inherits from its
272
+ * declaration applies to that row; it re-runs only this validator, not the whole chain.
238
273
  */
239
274
  private listenOn;
240
275
  boundToBinding(binding: FieldBase): void;
@@ -243,22 +278,21 @@ declare class CompareTo<T = any> extends Validator {
243
278
  unregisterFrom(binding: FieldBase): void;
244
279
  }
245
280
 
246
- /** What the validator remembers about one field it validates. */
281
+ /** The validator's state for one field it validates. */
247
282
  declare interface CompareToBindingState<T> extends ValidatorBindingState {
248
283
  oldValue: T;
249
284
  }
250
285
 
251
286
  /**
252
- * How the field to compare against is named. A field names it directly, a string names it by the name its
253
- * container holds it under, and a callback works it out from the field being validated. All three answer for the
254
- * record the validation is running over: handed the field of a `List`'s item template, a row compares against that
255
- * row's field.
287
+ * The element to compare against: the element itself, its name in its container, or a callback that returns it
288
+ * for the field being validated. All three are resolved within the record the validation runs over: given an
289
+ * element of a `List`'s item template, a row compares against that row's element.
256
290
  */
257
291
  declare type CompareToTarget = FieldBase | string | ((field: FieldBase) => FieldBase | null | undefined);
258
292
 
259
293
  /**
260
294
  * Sets the access of the elements it is registered on from the statement's result: `whenTrue` while the statement
261
- * holds, `whenFalse` otherwise.
295
+ * is true, `whenFalse` otherwise.
262
296
  */
263
297
  export declare class ConditionalAccessAction extends ConditionalStatementAction {
264
298
  constructor(statement: Statement, whenTrue?: Access, whenFalse?: Access);
@@ -270,39 +304,51 @@ export declare class ConditionalStatementAction extends ValueChangedAction {
270
304
  private readonly statement;
271
305
  private readonly conditionalExecutor;
272
306
  /**
273
- * What the elements this action was registered on were declared as. It holds declarations rather than the
274
- * elements themselves, so one entry stands for every row of a list, and the element a result is applied to is
275
- * the one that declaration names within the record the change happened in.
307
+ * The declarations of the elements this action was registered on. It holds declarations, not the elements, so one
308
+ * entry covers every row of a list; a result is applied to the element that corresponds to the declaration within
309
+ * the record the change happened in.
276
310
  */
277
311
  private readonly declarations;
278
312
  /**
279
- * The elements this action was registered on. Registration reaches one element at a time - the rows of a list
280
- * take the action on one by one, as they are built from the item template that carries it - so this is what
281
- * says which of the elements a declaration stands for the action actually drives.
313
+ * The elements this action was registered on. Registration happens one element at a time (the rows of a list
314
+ * receive the action one by one, as they are built from the item template), so this set determines which of the
315
+ * elements of a declaration the action controls.
282
316
  */
283
317
  private readonly registrations;
284
318
  constructor(statement: Statement, executorFn: ConditionalExecutorFn);
319
+ /**
320
+ * The listener on the fields the statement reads. The constructor installs it; it is removed when the action is
321
+ * taken off its last element and installed again when the action is next registered.
322
+ */
323
+ private readonly relay;
324
+ /** The number of elements the action is registered on; the relay is removed when it drops to zero. */
325
+ private registered;
326
+ private listening;
327
+ private listen;
285
328
  static get classIdentifier(): symbol;
286
329
  get eager(): boolean;
287
330
  boundToBinding(binding: FieldBase): void;
331
+ /** Forgets the result last applied to `binding`, so the next pass applies the statement over its new flags. */
332
+ resetBinding(binding: FieldBase): void;
288
333
  unregisterFrom(binding: FieldBase): void;
289
334
  /**
290
- * The elements of `scope` this action controls: what each declaration it serves names within that record, and of
291
- * those the ones that took the action on. A row of a list that never took it on is not one this action drives.
335
+ * The elements of `scope` this action controls: for each of its declarations, the corresponding elements within
336
+ * that record that the action is registered on. A row of a list the action is not registered on is skipped.
292
337
  */
293
338
  private targetsIn;
294
339
  /**
295
- * Re-evaluates the statement over one record and applies the result where it changed. The result is recorded
296
- * before the executor runs, because an executor that writes a value re-enters through that value's eager pass
297
- * and what it has to find there is the result being applied. It answers whether the record held anything for
298
- * this action to drive, which is how a caller learns that the record is not assembled yet.
340
+ * Re-evaluates the statement over one record and applies the result to every target whose last applied result
341
+ * differs, so a target registered after the result was applied to another one in the same record receives it.
342
+ * The result is recorded before the executor runs, because an executor that writes a value re-enters through that
343
+ * value's eager pass, which must see the result being applied. Returns whether the record contains a target for
344
+ * this action; false means the record is not assembled yet.
299
345
  */
300
346
  private applyIn;
301
347
  /**
302
- * Re-evaluates the records a change of `source` speaks for. A field of the record the targets live in speaks for
303
- * that record alone, which is what keeps one row of a list from answering for another; a field above them - a
304
- * form field every row reads - speaks for every record below it, and for the record the action was declared in
305
- * where the change reaches none.
348
+ * Re-evaluates the records affected by a change of `source`. A change of an element in the targets' record
349
+ * affects only that record, so one row of a list does not affect another; a change of an element above them (a
350
+ * form field every row reads) affects every record below it, or the record the action was declared in if there
351
+ * is no record below it.
306
352
  */
307
353
  private applyFrom;
308
354
  }
@@ -313,28 +359,31 @@ export declare class ConditionalValueAction<T> extends ConditionalStatementActio
313
359
 
314
360
  /**
315
361
  * Sets the visibility of the elements it is registered on from the statement's result: `whenTrue` while the
316
- * statement holds, `whenFalse` otherwise. Visibility is presentation alone, so what the elements send is left to
317
- * their access.
362
+ * statement is true, `whenFalse` otherwise. Visibility affects presentation only; what the elements send is
363
+ * determined by their access.
318
364
  */
319
365
  export declare class ConditionalVisibilityAction extends ConditionalStatementAction {
320
366
  constructor(statement: Statement, whenTrue?: Visibility, whenFalse?: Visibility);
321
367
  }
322
368
 
369
+ /** Sets what the devtools record and list. Does nothing in production. */
370
+ export declare function configureDevtools(options: DevtoolsOptions): void;
371
+
323
372
  /**
324
- * A form element that holds other elements and composes its state out of theirs: `Group`, which holds named
373
+ * A form element that holds other elements and composes its state from theirs: `Group`, which holds named
325
374
  * members, and `List`, which holds rows. Every element's `parent` is a `Container`.
326
375
  *
327
- * What a container answers for over its children is the same whatever holds them: `valid` and `busy` are composed
328
- * of theirs, `touched` is true where any child is touched and propagates an assignment down, `validate(true)`
329
- * revalidates every child before the container forms its own verdict, and a child's change of value or verdict
330
- * reaches the container through `notifyValueChanged()` and the tallies below. How the children are reached - by
331
- * name or by position - is the subclass's.
376
+ * The behaviour over children is the same in both subclasses: `valid` and `busy` are composed from the children's,
377
+ * `touched` is true if any child is touched and an assignment propagates down to every child, `validate(true)`
378
+ * revalidates every child before the container computes its own validity, and a child's change of value or
379
+ * validity reaches the container through `notifyValueChanged()` and the counters below. The subclass defines how
380
+ * children are addressed: by name or by position.
332
381
  */
333
382
  export declare abstract class Container<T = any, X extends object = Extras> extends FieldBase<T, X> {
334
383
  get [Symbol.toStringTag](): string;
335
384
  /**
336
- * The children this container holds, read through the tracked view of its state: a verdict or a flag composed
337
- * over them is formed again when a child is added or removed.
385
+ * The children this container holds, read through the tracked view of its state, so a validity or flag composed
386
+ * over them is recomputed when a child is added or removed.
338
387
  */
339
388
  protected abstract get children(): readonly FieldBase[];
340
389
  get touched(): boolean;
@@ -343,50 +392,77 @@ export declare abstract class Container<T = any, X extends object = Extras> exte
343
392
  get busy(): boolean;
344
393
  validate(revalidate?: boolean): void;
345
394
  /**
346
- * Records that a child changed its value, so that the transaction in progress works out at commit what this
347
- * container's own value became and announces it once. The mutation methods call it themselves; you rarely need
348
- * to.
395
+ * Records that a child changed its value, so that at commit the open transaction computes this container's new
396
+ * value and announces it once. The mutation methods call it; a direct call is rarely needed.
349
397
  */
350
398
  notifyValueChanged(): void;
399
+ /**
400
+ * Executes the action that confirms this container, with `params`, and returns what its `execute()` returns.
401
+ * The action is looked up in three steps; the first step that finds a candidate decides:
402
+ *
403
+ * 1. an action at or below this container with a `SubmitAction` whose target is this container;
404
+ * 2. an action with `defaultConfirm` among the direct members;
405
+ * 3. an action with `defaultConfirm` at a lower level.
406
+ *
407
+ * Only actions whose `visibility` is `'full'` are candidates. One candidate is executed if it is `executable`;
408
+ * where it is not, nothing is executed. Two or more candidates in one step are ambiguous: nothing is executed and
409
+ * a warning is logged. Returns undefined where nothing is executed. A rendering layer calls it for a confirm
410
+ * gesture, such as Enter in a dialog.
411
+ */
412
+ confirm(params?: any): Promise<any> | undefined;
413
+ /**
414
+ * Executes the action that rejects this container, looked up as in `confirm()` with `RejectAction` and
415
+ * `defaultReject`. A rendering layer calls it for a reject gesture, such as Escape in a dialog.
416
+ */
417
+ reject(params?: any): Promise<any> | undefined;
418
+ /**
419
+ * A container whose members are all actions, such as a bar of buttons, holds no data and sends nothing, like an
420
+ * action. A container without members, or with at least one member that is not an action, sends as its access
421
+ * determines.
422
+ */
423
+ protected serializesAs(purpose: 'value' | 'fullValue'): 'value' | 'null' | 'omit';
424
+ /** The action `confirm()` or `reject()` executes, or undefined. */
425
+ private command;
426
+ /** Every action at or below this container, depth-first in member order, with its depth below this container. */
427
+ private actionsBelow;
351
428
  protected get composesValue(): boolean;
352
429
  /**
353
- * A container with nothing listening for what it holds does not compose it at all, so the copy it keeps is from
354
- * before the changes nobody received. A registration that adds a listener brings it up to date here, and what
355
- * the listener is then told about is the change that follows it.
430
+ * A container with no listener for what it holds does not compose it, so its stored copy predates the
431
+ * unannounced changes. A registration that adds a listener updates the copy here, so the listener receives the
432
+ * changes made after the registration.
356
433
  */
357
434
  protected refreshPreviousValue(): void;
358
435
  /** A container holds every member's value whatever the member sends: its `fullValue`. */
359
436
  protected get holding(): any;
360
437
  /**
361
- * The composed verdict `valid` answers with, memoised by Vue. The walk over the children is what makes an error
362
- * pushed into one of them visible without a validate() call, and the computed keeps that walk from repeating
363
- * while nothing it read has moved.
438
+ * The composed validity `valid` returns, memoised by Vue. The walk over the children makes an error written into
439
+ * one of them visible without a validate() call, and the computed skips the walk while nothing it read has
440
+ * changed.
364
441
  */
365
442
  private get validRead();
366
443
  /**
367
- * The composed answer `busy` gives, memoised by Vue. An `Action` counts its executions in a counter of its own,
368
- * which no container is told about, so the answer is composed over the children instead of tallied; the computed
369
- * keeps the walk from repeating while nothing it read has moved, and a child that is itself a container answers
370
- * from its own computed.
444
+ * The composed value of `busy`, memoised by Vue. An `Action` counts its executions in its own counter, which does
445
+ * not notify containers, so the value is composed over the children; the computed skips the walk while nothing
446
+ * it read has changed, and a child that is a container reads its own computed.
371
447
  */
372
448
  private get busyRead();
373
449
  /**
374
- * Records that a child started or stopped answering `validating` with true, and carries the transition further
375
- * up where it changes this container's own answer.
450
+ * Records that a child's `validating` became true or false, and passes the transition up if it changes this
451
+ * container's own `validating`.
376
452
  */
377
453
  protected childValidatingChanged(started: boolean): void;
378
454
  /**
379
- * Records a child's new verdict in this container's tally. The child reports it as it settles, and the commit
380
- * settles the deepest element first, so the tally a container reads when its own turn comes is finished. The
381
- * delta is applied here rather than recomputed by walking the children at commit, which would cost
382
- * `O(children)` per container and turn a list fill back into the quadratic walk this tally exists to avoid.
455
+ * Records a child's new validity in this container's invalid count. The child calls it as it settles, and the
456
+ * commit settles the deepest element first, so the count is complete when the container settles. The delta is
457
+ * applied here; recomputing by walking the children at commit would cost `O(children)` per container and make
458
+ * filling a list quadratic.
383
459
  */
384
460
  protected childValidityChanged(nowValid: boolean): void;
385
461
  }
386
462
 
387
463
  /**
388
- * What a container holds beyond the common slots: the object the value getter last built, together with the
389
- * version of the tree it was built from.
464
+ * What a container holds beyond the common slots: the object the value getter last built, and the version of the
465
+ * tree it was built from.
390
466
  */
391
467
  declare interface ContainerSlots<T = any> extends ElementSlots<T> {
392
468
  cachedValue: T;
@@ -394,15 +470,15 @@ declare interface ContainerSlots<T = any> extends ElementSlots<T> {
394
470
  }
395
471
 
396
472
  /**
397
- * Told what an element contributes to its container's `value` once that changed over a transaction: the element's
398
- * value where its access sends it, `null` for `'disabled-null'`, and `undefined` for `'disabled'`, whose key or row
399
- * is left out. The pair carried is (contribution now, contribution at the last announcement).
473
+ * Fires when what an element sends to its container's `value` changed over a transaction: the element's value if
474
+ * its access sends it, `null` for `'disabled-null'`, and `undefined` for `'disabled'`, whose key or row is omitted.
475
+ * The parameters are (contribution now, contribution at the last announcement).
400
476
  *
401
- * It answers a different question from `ValueChangedAction`, which reports what the element holds. A write into a
402
- * `'disabled'` field changes what the field holds and not what it sends, so it fires `ValueChangedAction` alone;
403
- * switching a field's access changes what it sends and not what it holds, so it fires this action alone. On a
404
- * container, what it holds is its `fullValue` and what it sends is its `value`, so a change of a member's access
405
- * reaches the containers above as a change of their contribution, never of their value.
477
+ * `ValueChangedAction` reports what the element holds; this action reports what it sends. A write into a
478
+ * `'disabled'` field changes what the field holds and not what it sends, so it fires only `ValueChangedAction`;
479
+ * changing a field's access changes what it sends and not what it holds, so it fires only this action. A container
480
+ * holds its `fullValue` and sends its `value`, so a change of a member's access fires this action on the
481
+ * containers above, and not `ValueChangedAction`.
406
482
  */
407
483
  export declare class ContributionChangedAction<T = any> extends FieldActionBase {
408
484
  constructor(executorFn: (field: FieldBase<T>, supr: FieldActionExecute<T>, newValue: unknown, oldValue: unknown) => void);
@@ -410,87 +486,131 @@ export declare class ContributionChangedAction<T = any> extends FieldActionBase
410
486
  execute(field: FieldBase<T>, supr: FieldActionExecute<T>, newValue: unknown, oldValue: unknown): void;
411
487
  }
412
488
 
413
- /** What an element's access is when nothing sets it. */
489
+ /** The keys of the members that send something: every member except an `Action`. */
490
+ declare type DataKeys<T extends GenericFieldsInterface> = {
491
+ [K in keyof T]: T[K] extends Action<any, any> ? never : K;
492
+ }[keyof T];
493
+
494
+ /** The default access of an element. */
414
495
  export declare const defaultAccess: Access;
415
496
 
416
- /** What an element's visibility is when nothing sets it. */
497
+ /** The default visibility of an element. */
417
498
  export declare const defaultVisibility: Visibility;
418
499
 
419
500
  /**
420
- * The mutable state of one element, held in an object of its own beside the element rather than in the element's
421
- * own properties.
501
+ * Names `element` for the devtools and lists it in opt-in mode. `name` replaces the element's class and number,
502
+ * `file` the file found from the constructing code. Does nothing in a production build.
503
+ */
504
+ export declare function describeState(element: FieldBase, description: StateDescription): void;
505
+
506
+ /** What `configureDevtools()` sets. A member left out keeps its setting. */
507
+ export declare interface DevtoolsOptions {
508
+ /**
509
+ * Whether the devtools record and list elements. Defaults to true. While false, nothing is recorded or listed;
510
+ * an element built while false is not listed after it is set back to true.
511
+ */
512
+ enabled?: boolean;
513
+ /**
514
+ * Which root elements are listed: `'opt-out'` (default) every one that is not hidden, `'opt-in'` only those
515
+ * named with `describeState()`.
516
+ */
517
+ registration?: DevtoolsRegistration;
518
+ /**
519
+ * Whether the stack is captured when a root element is constructed, to show the file that constructed it.
520
+ * Defaults to true. While false, an element's file is the one `describeState()` gives, or none.
521
+ */
522
+ location?: boolean;
523
+ }
524
+
525
+ /** Which elements the devtools list: every root element except the hidden ones, or only the described ones. */
526
+ export declare type DevtoolsRegistration = 'opt-out' | 'opt-in';
527
+
528
+ /**
529
+ * The mutable state of one element, held in a separate object, not in the element's own properties.
422
530
  *
423
- * An element reaches it through two views of that one object, both in private class fields of `FieldBase`:
531
+ * An element accesses it through two views of that object, both in private class fields of `FieldBase`:
424
532
  * `this.state` is `reactive(slots)` and `this.raw` is the object itself. A slot read through `state` inside a
425
- * render effect or a computed subscribes that effect to the slot, and a write to the slot re-runs it. The
426
- * bookkeeping an element does for itself goes through `raw`, which neither records a read nor announces a write.
427
- * The value cache of a container goes through `raw` in particular: its getter writes the cache while it runs, and
428
- * a tracked write there costs the reading effect one extra evaluation, and one extra render on mount, for a value
429
- * it has already built.
533
+ * render effect or a computed subscribes that effect to the slot, and a write to the slot re-runs it. The element's
534
+ * internal bookkeeping goes through `raw`, which neither tracks a read nor triggers on a write. This includes a
535
+ * container's value cache: its getter writes the cache while it runs, and a tracked write there would cost the
536
+ * reading effect one extra evaluation, and one extra render on mount, for a value already built.
430
537
  *
431
- * Being private class fields is what puts the two views out of reach of everything outside `FieldBase`: a private
432
- * field is absent from `Object.keys`, `JSON.stringify`, `Object.getOwnPropertySymbols` and lodash `getAllKeys` by
433
- * construction, and needs no per-instance property definition to be. Both `JSON.stringify` and lodash `isEqual`
434
- * walk their way down a structure over own keys, enumerable symbols included, and the `parent` slot is in the
435
- * state: reachable, it would take either walker back into the container the element came from.
538
+ * As private class fields, the two views are not accessible outside `FieldBase`: a private field is absent from
539
+ * `Object.keys`, `JSON.stringify`, `Object.getOwnPropertySymbols` and lodash `getAllKeys` without any per-instance
540
+ * property definition. `JSON.stringify` and lodash `isEqual` both walk a structure over own keys, enumerable
541
+ * symbols included, and the `parent` slot is in the state: if reachable, it would lead either walk back into the
542
+ * element's container.
436
543
  *
437
- * What they do reach on an element is `_actions` once something is registered, `_fields` and the guarded view
438
- * over it on a `Group`, and `_itemTemplate` on a `List`. All of them lead downwards only.
544
+ * The own properties those walks do reach on an element are `_actions` once something is registered, `_fields` on
545
+ * a `Group`, and `_itemTemplate` on a `List`. All of them lead downwards only.
439
546
  */
440
547
  declare interface ElementSlots<T = any> {
441
548
  /** the value the element was given at construction; isChanged compares against it */
442
549
  originalValue: T;
443
550
  /**
444
- * What the last ValueChangedAction reported the element as holding - its value, and a container's fullValue; the
445
- * next transaction measures its net change against it
551
+ * The value the last ValueChangedAction reported for the element (its value; a container's fullValue); the next
552
+ * transaction compares its net change against it
446
553
  */
447
554
  announcedValue: T;
448
555
  /**
449
- * What the last ContributionChangedAction reported the element as contributing to its container: its value,
450
- * `null`, or `undefined` for nothing
556
+ * What the last ContributionChangedAction reported the element as sending to its container: its value, `null`,
557
+ * or `undefined` for nothing
451
558
  */
452
559
  announcedContribution: unknown;
453
560
  /**
454
- * What a container's own validators last ran over - what it sends; the next transaction runs them where that
455
- * moved. A leaf's validators run at the write and the access switch, and leave it untouched.
561
+ * What a container's own validators last ran over (what it sends); the next transaction runs them again if that
562
+ * changed. A leaf's validators run at the write and at an access change that changes what it sends, and do not
563
+ * use this slot.
456
564
  */
457
565
  validatedValue: unknown;
458
566
  errors: ValidationError[];
459
567
  visibility: Visibility;
460
568
  access: Access;
461
- /** counts the writes that changed the value of the element or of anything below it */
569
+ /** counts the writes that changed the value of the element or of any element below it */
462
570
  valueVersion: number;
463
- /** how many asynchronous validation runs are in flight on this element */
571
+ /** the number of asynchronous validation runs in flight on this element */
464
572
  validatingCount: number;
465
- /** how many direct children answer `validating` with true; a child that starts or stops running moves it */
573
+ /** the number of direct children whose `validating` is true; updated when a child starts or stops validating */
466
574
  validatingChildren: number;
467
- /** the container that holds this element, absent while none does; takeChild writes it, releaseChild clears it */
575
+ /** the container that holds this element, or undefined; takeChild writes it, releaseChild clears it */
468
576
  parent: Container | undefined;
469
- /** the name the containing Group holds this element under; a List row carries none */
577
+ /** the name the containing Group holds this element under; undefined for a List row */
470
578
  fieldName: string | undefined;
471
579
  /** generation of the validators attached to the element; clearValidators() raises it */
472
580
  validationEpoch: number;
473
581
  /**
474
- * The extended properties the element carries, typed by the element's own X parameter. A write replaces the
475
- * object rather than writing into it, so an effect that read the slot re-runs on the write, and the object a
476
- * transaction captured is the one a rollback puts back.
582
+ * The element's extended properties, typed by the element's X parameter. A write replaces the object instead of
583
+ * modifying it, so an effect that read the slot re-runs on the write, and a rollback restores the object the
584
+ * transaction captured.
477
585
  */
478
586
  extra: object;
479
587
  /**
480
- * The element this one was bound from, absent on an element that was declared rather than bound. It is what lets
481
- * an action shared by every binding work out which binding of a second element it means: `declaration` is the
482
- * canonical one, so a binding of a binding names the element the whole family was declared as.
588
+ * The declaration this element was bound from; undefined on an element that was not bound. An action shared by
589
+ * every binding uses it to determine which binding of a second element applies: the slot holds the canonical
590
+ * declaration, so a binding of a binding refers to the original declaration.
483
591
  */
484
592
  declaration: FieldBase | undefined;
485
- /** the verdict the last commit announced, which is what a change of validity is measured against */
593
+ /**
594
+ * The access and the visibility the last commit announced, recorded by the first write of either in a
595
+ * transaction and cleared once the commit announced the net change; undefined while no change is pending.
596
+ */
597
+ announcedAccess: Access | undefined;
598
+ announcedVisibility: Visibility | undefined;
599
+ /** the validity the last commit announced; a change of validity is detected against it */
486
600
  valid: boolean;
487
- /** number of direct children whose last announced verdict was invalid */
601
+ /** the number of direct children whose last announced validity was invalid */
488
602
  invalidChildren: number;
603
+ /**
604
+ * What the element held when its errors of an origin other than `'validator'` were written, which a `touched`
605
+ * write compares against for the errors removed on `'edit'`. `NoErrorsBaseline` while there is none to compare
606
+ * against, and `ChangedSinceErrors` where the value changed before one was recorded.
607
+ */
608
+ errorsBaseline: unknown;
489
609
  }
490
610
 
491
611
  /**
492
- * Told once a write of `access` changed `enabled`: a switch into or out of `'editable'`. It fires after
493
- * `AccessChangedAction`, and a switch between two accesses that are not `'editable'` does not fire it.
612
+ * Fires after a write of `access` changed `enabled`: a change into or out of `'editable'`. It fires after
613
+ * `AccessChangedAction`; a change between two accesses that are not `'editable'` does not fire it.
494
614
  */
495
615
  export declare class EnabledChangedAction extends FieldActionBase {
496
616
  constructor(executorFn: (field: FieldBase, supr: FieldActionExecute, newValue: boolean, oldValue: boolean) => void);
@@ -499,10 +619,11 @@ export declare class EnabledChangedAction extends FieldActionBase {
499
619
  }
500
620
 
501
621
  /**
502
- * Asked before a write of `access` that would change `enabled`: a switch into or out of `'editable'`. It is asked
503
- * after `AccessChangingAction`, over the access that would be written. `enabled` is read from `access`, so the
504
- * answer cannot set it: answering with the value `enabled` has now, or throwing `AbortEventHandlingException`,
505
- * refuses the write of `access`, and answering with the new value, `null` or `undefined` lets it through.
622
+ * Fires before a write of `access` that would change `enabled`: a change into or out of `'editable'`. It fires
623
+ * after `AccessChangingAction`, for the access that would be written. `enabled` is read from `access`, so the
624
+ * return value cannot set it: returning the current value of `enabled`, or throwing
625
+ * `AbortEventHandlingException`, cancels the write of `access`; returning the new value, `null` or `undefined`
626
+ * allows it.
506
627
  */
507
628
  export declare class EnabledChangingAction extends FieldActionBase {
508
629
  constructor(executorFn: (field: FieldBase, supr: FieldActionExecute, newValue: boolean, oldValue: boolean) => boolean);
@@ -511,22 +632,110 @@ export declare class EnabledChangingAction extends FieldActionBase {
511
632
  }
512
633
 
513
634
  /**
514
- * Where an error comes from. `'validator'` is an error a validator produced, `'server'` one the server returned and
515
- * `'application'` one the application's own code computed and wrote into `errors`. Any other string is an origin of
516
- * the application's own.
635
+ * The content of an error: what failed, the values it failed with, an English sentence describing it, and its
636
+ * origin. An error the application builds from a server's response has the same content, so a renderer converts
637
+ * validator and server errors to text with one function.
638
+ */
639
+ export declare interface ErrorDescription {
640
+ /** Machine-readable identifier of what failed, in snake_case. */
641
+ readonly code: string;
642
+ /** The values of the failure, such as `minValue` for `min_value`. */
643
+ readonly params: Readonly<Record<string, unknown>>;
644
+ /** The failure in English, plain text, with `params` substituted. */
645
+ readonly detail: string;
646
+ /** The origin of the error; see `ValidationError.origin`. */
647
+ readonly origin: ErrorOrigin;
648
+ }
649
+
650
+ /**
651
+ * The source of an error. `'validator'` is an error a validator produced, `'server'` one the server returned and
652
+ * `'application'` one the application's code computed and wrote into `errors`. Any other string is an
653
+ * application-defined origin.
654
+ *
655
+ * Every origin but `'validator'` has a rule stating whether its errors count toward validity and when an element
656
+ * removes them; see `ErrorPolicy`.
517
657
  */
518
658
  export declare type ErrorOrigin = 'validator' | 'server' | 'application' | (string & {});
519
659
 
660
+ /** A rule per origin. `'validator'` has no rule: a validator replaces its own errors and they always count. */
661
+ export declare type ErrorPolicies = Readonly<Partial<Record<Exclude<ErrorOrigin, 'validator'>, ErrorPolicyRule>>>;
662
+
663
+ /**
664
+ * Key of the `FieldBase` method that recomputes the validity of every element in its subtree that holds an error
665
+ * of an origin other than `'validator'`, after the rules over those errors may have changed. `ErrorPolicy` calls
666
+ * it; the package does not export it.
667
+ */
668
+ declare const ErrorPoliciesChanged: unique symbol;
669
+
670
+ /**
671
+ * The rules of the error origins for the element it is registered on and every element below it. An element takes
672
+ * the rule of an origin from the nearest `ErrorPolicy` that names it, on itself or on a container above it; an
673
+ * origin no such policy names takes the rule `setDefaultErrorPolicies` set.
674
+ *
675
+ * ```typescript
676
+ * login.registerAction(new ErrorPolicy({ server: { validEffect: false, removeOn: 'submit' } }));
677
+ * ```
678
+ *
679
+ * Its registration is shared by the element's bindings, as every action's is. Registering or unregistering it
680
+ * recomputes the validity of the elements below it; an error it now removes stays until the event that removes
681
+ * it. The constructor throws a TypeError for a rule of `'validator'`, a `validEffect` that is not a boolean, a
682
+ * `removeOn` that is not an `ErrorRemoval`, and `validEffect: true` with `removeOn: 'submit'`, since such an error
683
+ * refuses the submit that would remove it. Registering it beside another `ErrorPolicy` that names one of its
684
+ * origins throws a TypeError.
685
+ */
686
+ export declare class ErrorPolicy extends FieldActionBase {
687
+ readonly policies: ErrorPolicies;
688
+ constructor(policies: ErrorPolicies);
689
+ static get classIdentifier(): symbol;
690
+ boundToBinding(binding: FieldBase): void;
691
+ unregisterFrom(binding: FieldBase): void;
692
+ private rulesChanged;
693
+ }
694
+
695
+ /** How the errors of one origin are treated. */
696
+ export declare interface ErrorPolicyRule {
697
+ /** Whether an error of the origin makes its element, and every container above it, invalid. */
698
+ readonly validEffect: boolean;
699
+ /** When an element removes an error of the origin by itself. */
700
+ readonly removeOn: ErrorRemoval;
701
+ }
702
+
703
+ /**
704
+ * When an element removes an error by itself:
705
+ *
706
+ * - `'change'`: when the element's value changes. A container's value changes with any member or row below it, and
707
+ * when a member or a row is added, removed or written a different `access`.
708
+ * - `'edit'`: when `touched = true` is written on the element or on an element below it, and the element's value
709
+ * differs from the value it held when the error was written.
710
+ * - `'submit'`: when a `SubmitAction` whose target is the element or a container above it sends the target's value.
711
+ * - `'never'`: only the code that wrote the error removes it.
712
+ */
713
+ export declare type ErrorRemoval = 'change' | 'edit' | 'submit' | 'never';
714
+
715
+ /** The values of `ErrorRemoval`. */
716
+ export declare const errorRemovals: readonly ErrorRemoval[];
717
+
520
718
  export declare class ExecuteAction extends FieldActionBase {
521
719
  constructor(executorFn: (field: FieldBase, supr: FieldActionExecute, params: any) => any);
522
720
  static get classIdentifier(): symbol;
523
721
  execute(field: FieldBase, supr: FieldActionExecute, params: any): any;
722
+ /**
723
+ * Whether this handler can run now on `action`. `Action.executable` is false while any of the action's
724
+ * `ExecuteAction` handlers returns false. The base class returns true; a subclass overrides it with a condition
725
+ * that a template can bind to, such as the validity of the form a `SubmitAction` sends. The read is reactive where
726
+ * the condition reads reactive state.
727
+ */
728
+ canExecute(action: FieldBase): boolean;
524
729
  }
525
730
 
731
+ /** Key of the `Action` method that lists its `ExecuteAction` handlers; `Container` calls it, and the package does not
732
+ * export it. */
733
+ declare const ExecuteHandlers: unique symbol;
734
+
526
735
  /**
527
- * The extended properties an element carries when nothing states otherwise. It is empty as declared and exists
528
- * to be augmented: the layer that renders the elements declares what it renders them with, and every element in
529
- * the application then carries those properties without a type argument at any construction site.
736
+ * The default type of an element's extended properties. It is declared empty, to be augmented: the rendering
737
+ * layer declares the properties it renders elements with, and every element in the application then has those
738
+ * properties without a type argument at any construction site.
530
739
  *
531
740
  * ```ts
532
741
  * declare module '@dynamicforms/vue-forms' {
@@ -538,11 +747,10 @@ export declare class ExecuteAction extends FieldActionBase {
538
747
  * }
539
748
  * ```
540
749
  *
541
- * The interface is one per application, so two packages that both declare a property of the same name must give
542
- * it the same type; declaration merging refuses a second declaration that differs.
750
+ * There is one interface per application, so two packages that declare a property of the same name must give it
751
+ * the same type; declaration merging rejects a second declaration with a different type.
543
752
  *
544
- * An element that states an X of its own replaces this rather than adding to it, so an element that carries both
545
- * is `Field<string, Extras & Local>`.
753
+ * An explicit X type argument replaces this interface, so an element with both is `Field<string, Extras & Local>`.
546
754
  */
547
755
  export declare interface Extras {
548
756
  }
@@ -551,23 +759,29 @@ export declare class Field<T = any, X extends object = Extras> extends FieldBase
551
759
  get [Symbol.toStringTag](): string;
552
760
  protected get state(): FieldSlots<T>;
553
761
  protected get raw(): FieldSlots<T>;
554
- /** the value slot itself, without the notifications the value setter carries around a write */
762
+ /** the value slot itself, without the notifications the value setter sends on a write */
555
763
  protected get _value(): T;
556
764
  protected set _value(newValue: T);
557
765
  constructor(params?: IFieldParams<T, X>);
558
766
  /**
559
- * Applies the constructor parameters. It is a hook so that a subclass needing different parameter handling
560
- * overrides one method instead of redeclaring the constructor - Action does exactly that.
767
+ * Applies the constructor parameters. A subclass that needs different parameter handling overrides this method
768
+ * instead of redeclaring the constructor, as Action does.
561
769
  *
562
- * It is called from this constructor, so it runs before a subclass's own class field initializers, which
563
- * only run once super() returns. An override must therefore work off its parameters alone: members the
564
- * subclass initializes read as undefined inside it, and anything it writes to such a member is overwritten
565
- * the moment the initializer runs.
770
+ * It is called from this constructor, so it runs before a subclass's class field initializers, which run after
771
+ * super() returns. An override can therefore use only its parameters: members the subclass initializes are
772
+ * undefined inside it, and a value it writes to such a member is overwritten when the initializer runs.
566
773
  */
567
774
  protected init(params?: IFieldParams<T, X>): void;
568
775
  get value(): T;
569
776
  set value(newValue: T);
777
+ /** The implementation of `PluginContext.changeInPlace`. */
778
+ protected [ChangeInPlace](write: () => void, undo: () => void, copy: () => T): void;
570
779
  get touched(): boolean;
780
+ /**
781
+ * Whether the user has interacted with the field. A rendering layer writes `true` when the user leaves the input;
782
+ * the write removes the errors whose rule removes them on `'edit'` from the field and the containers above it,
783
+ * where their values changed since those errors were written (see `ErrorPolicy`).
784
+ */
571
785
  set touched(touched: boolean);
572
786
  bind(data?: T, overrides?: IBindParams<T, X>): this;
573
787
  }
@@ -577,34 +791,44 @@ export declare abstract class FieldActionBase {
577
791
  get classIdentifier(): symbol;
578
792
  private readonly executorFn;
579
793
  /**
580
- * What this action remembers about one of the elements it serves. An action instance is shared - a `List` row
581
- * carries the instances the item template carries - so anything an action holds about the element it last ran
582
- * over belongs to that element rather than to the action: a verdict, a sequence number, a listener it installed.
583
- * The keys are weak, so what an action remembers about a row is released with the row.
794
+ * The per-element state of this action. An action instance is shared (a `List` row has the same instances as
795
+ * the item template), so state about the element it runs over is stored per element: a validation result, a
796
+ * sequence number, a listener it installed. The keys are weak, so the state for a row is released with the row.
584
797
  */
585
798
  private readonly states;
586
799
  constructor(executorFn: ActionExecutor);
587
800
  /**
588
- * This action's state for `key`, created by `init` the first time it is asked for. The key is the element the
589
- * action is running over, or the record that element belongs to where what is remembered is a fact about the
590
- * whole record.
801
+ * Returns this action's state for `key`, created by `init` on first access. The key is the element the action
802
+ * runs over, or the record that element belongs to if the state concerns the whole record.
591
803
  */
592
804
  protected state<S>(key: object, init: () => S): S;
805
+ /**
806
+ * Drops this action's state for `key`, so the next `state()` call creates it again. A rollback of the operation
807
+ * that dropped it puts it back.
808
+ */
809
+ protected forgetState(key: object): void;
593
810
  execute(field: FieldBase, supr: FieldActionExecute, ...params: any[]): any;
594
811
  get eager(): boolean;
595
812
  /**
596
- * Announces that this action now serves `binding`. It runs once per element the action is registered on, the
597
- * copies of that element included: a copy takes on the instances it was copied from and each is told about the
598
- * copy as it does.
813
+ * Called when this action is bound to `binding`. It runs once per element the action is registered on, bindings
814
+ * of that element included: a binding uses the action instances of its declaration, and each is called with the
815
+ * binding.
599
816
  */
600
817
  boundToBinding(binding: FieldBase): void;
601
818
  /**
602
- * Announces that `binding` no longer holds this action, and takes back what running it left there. It names one
603
- * element rather than the action as a whole, because the instance goes on serving every other element it was
604
- * registered on. It runs inside the operation that drops the registration, so an operation that unwinds puts the
605
- * registration and what this took back both back.
819
+ * Called when `binding` no longer has this action; an override removes what running the action left on it. It
820
+ * receives one element because the same instance stays registered on other elements. It runs inside the
821
+ * operation that removes the registration, so a rollback of that operation restores both the registration and
822
+ * what this method removed.
606
823
  */
607
824
  unregisterFrom(binding: FieldBase): void;
825
+ /**
826
+ * Called when `binding` is reset to a new binding of its declaration: a member of a bound group, or a `List` row
827
+ * reused for another record. An override drops what it keeps about the element's state before the reset; the
828
+ * element's eager actions other than the validators run again once the reset holds every new value, before the
829
+ * baseline is recorded.
830
+ */
831
+ resetBinding(binding: FieldBase): void;
608
832
  }
609
833
 
610
834
  export declare type FieldActionExecute<T = any> = (field: FieldBase<T>, ...params: any[]) => any;
@@ -612,29 +836,26 @@ export declare type FieldActionExecute<T = any> = (field: FieldBase<T>, ...param
612
836
  export declare abstract class FieldBase<T = any, X extends object = Extras> {
613
837
  #private;
614
838
  /**
615
- * Vue's getTargetType answers INVALID for an object that carries __v_skip, so reactive() hands an element back
616
- * unwrapped and no element is ever behind a proxy of its own. isReactive() reads the second flag, and it stays
617
- * true because what carries an element's reactivity - its state - is a reactive object.
839
+ * Vue's getTargetType returns INVALID for an object that has __v_skip, so reactive() returns an element
840
+ * unwrapped and no element is wrapped in a proxy of its own. isReactive() reads the second flag, which is true
841
+ * because the element's state, which holds its reactivity, is a reactive object.
618
842
  *
619
- * Two consequences for a consumer, both silent. watch(field, cb) with a bare element as the source registers
620
- * no dependency, because the deep traversal Vue starts for a reactive source stops on __v_skip; the supported
621
- * form is watch(() => field.value, cb). And readonly(field) hands the element straight back, so the value it
622
- * returns is the element itself and a write through it reaches the field; what a caller hands out instead is
623
- * the value, which is frozen, or a computed over it.
843
+ * Two consequences for a consumer, neither of which raises an error. watch(field, cb) with a bare element as the
844
+ * source registers no dependency, because Vue's deep traversal of a reactive source stops on __v_skip; use
845
+ * watch(() => field.value, cb). readonly(field) returns the element itself, so a write through the result
846
+ * reaches the field; to pass a read-only view, pass the value (which is frozen) or a computed over it.
624
847
  */
625
848
  get __v_skip(): boolean;
626
849
  get __v_isReactive(): boolean;
627
850
  /**
628
- * Names the element's class, which is what a structural comparison of two elements answers on. An element keeps
629
- * its state in private class fields, so a walk over own keys reaches none of it; lodash reads this tag through
630
- * Object.prototype.toString before it compares anything, and a tag it does not know ends the comparison there.
631
- * Two elements are therefore equal only where they are the same element. What they hold is compared as
632
- * isEqual(a.value, b.value).
851
+ * The tag that a structural comparison of two elements uses. An element keeps its state in private class fields,
852
+ * so a walk over own keys reaches none of it. lodash reads this tag through Object.prototype.toString before it
853
+ * compares anything and stops at a tag it does not recognise, so two elements are equal only if they are the
854
+ * same element. The package's own `isEqual` compares an element by the value it holds.
633
855
  *
634
- * It is an accessor on the prototype, so an element carries nothing for it, and `Object.prototype.toString`
635
- * answers `[object Field]` rather than `[object Object]`. Each class states its own name as a literal: a
636
- * minifier renames the class itself, so reading the constructor's name would report whatever the build called
637
- * it.
856
+ * It is an accessor on the prototype, so it adds no own property to an element, and `Object.prototype.toString`
857
+ * returns `[object Field]` instead of `[object Object]`. Each class declares its name as a literal, because a
858
+ * minifier renames the class and the constructor's name would be the minified one.
638
859
  */
639
860
  get [Symbol.toStringTag](): string;
640
861
  constructor(slots: ElementSlots<T>);
@@ -647,345 +868,413 @@ export declare abstract class FieldBase<T = any, X extends object = Extras> {
647
868
  abstract get touched(): boolean;
648
869
  abstract set touched(touched: boolean);
649
870
  /**
650
- * A new element of this one's class over `data`: same class, same registered actions, same extended properties,
651
- * and the change history starting over. It is how a declaration is put to work over a record - every row a
652
- * `List` builds is its item template bound to that row's data - and the element it is called on is what the new
653
- * one answers `declaration` with.
871
+ * Returns a new element of this one's class over `data`, with the same registered actions and extended
872
+ * properties and a new change history. Every row a `List` builds is its item template bound to that row's data.
873
+ * The new element's `declaration` is the element `bind()` is called on.
654
874
  *
655
- * `data` of `undefined` is no data supplied and the new element carries what this one holds; an explicit `null`
656
- * is data and clears. `overrides` states the rest: `originalValue` is read by key presence, `access` and
657
- * `visibility` fall back to this element's, and extended properties it names are written over the ones carried
658
- * over. The new element is detached - no `parent`, no `fieldName` - so it is free to be taken by a container.
875
+ * `data` of `undefined` means no data: the new element holds what this one holds. An explicit `null` is data and
876
+ * clears the value. In `overrides`, `originalValue` is applied when the key is present, `access` and `visibility`
877
+ * default to this element's, and the extended properties given are written over the copied ones. The new element
878
+ * is detached (no `parent`, no `fieldName`), so a container can take it.
659
879
  */
660
880
  abstract bind(data?: T, overrides?: IBindParams<T, X>): FieldBase<T, X>;
661
881
  /**
662
- * Exchanges the data this element holds for `data`, in place. The element is the same instance afterwards - its
663
- * identity, its actions, its extended properties and its place in whatever container holds it all stand - and it
664
- * ends up in the state `bind(data)` would have produced: the values are written, the change history starts over
665
- * and the validators run. It is what recycles one element across records, which is what a virtualised renderer
666
- * does with the rows it keeps.
882
+ * Replaces the data this element holds with `data`, in place. The instance, its actions, its extended properties
883
+ * and its position in its container are unchanged, and the element ends in the state `bind(data)` produces: the
884
+ * values are written, the change history starts over and the validators run. A virtualised renderer uses it to
885
+ * reuse one element across records.
667
886
  *
668
- * The element makes no statement of its own about the exchange: no `ValueChangedAction` fires for it, the way
669
- * none fires for an element that was just built. Its members do announce theirs, and a verdict that moves is
670
- * announced as always - a rebound element that is invalid says so to the container holding it. A change an
671
- * open transaction is already owed an announcement for stands: the commit reports the pair measured from
672
- * where the element was when the transaction opened.
887
+ * No `ValueChangedAction` fires for the element itself, as for a newly built element. Its members announce their
888
+ * changes, and a change of validity is announced as usual: a rebound element that is invalid updates the invalid
889
+ * count of its container. If an open transaction already has a pending value change for the element, the commit
890
+ * announces it with the value the element had when the transaction opened as the old value.
673
891
  *
674
- * The data is measured against the element's `declaration`, so a key a record leaves out is taken from the
675
- * declaration rather than left as the previous record had it.
892
+ * A member of a `Group` whose key is missing from `data` takes the `originalValue` of the corresponding member of
893
+ * the group's `declaration`: for a group that is its own declaration, the member's own baseline. A key missing
894
+ * from the data never takes the value of the previous record.
895
+ *
896
+ * The element keeps its `access` and `visibility`. A member reset from an element other than itself (a member of
897
+ * a bound group, a reused `List` row) takes them from that element, see `resetChild`.
676
898
  */
677
899
  rebind(data: T): this;
678
900
  /** contains original field value as was provided at creation */
679
901
  get originalValue(): T;
680
902
  set originalValue(newValue: T);
681
903
  /**
682
- * The extended properties this element carries: what a consumer attached to it beyond the members the class
683
- * declares, such as the label, hint or css class a UI layer binds to the input it renders the element with.
684
- * The read is tracked, so a template rendering off `field.extra.label` re-renders when the property is written.
904
+ * The extended properties of this element: properties a consumer attached beyond the members the class declares,
905
+ * such as the label, hint or css class a UI layer binds to the input it renders for the element. The read is
906
+ * tracked, so a template that reads `field.extra.label` re-renders when the property is written.
685
907
  *
686
- * Every property is optional here, whatever `X` states: a parameter object need not carry one and
687
- * setExtendedValues writes as few as a caller likes, so a property `X` declares as required is present only
688
- * once something has written it.
908
+ * Every property is optional here, whatever `X` declares: a parameter object need not contain any, and
909
+ * setExtendedValues can write any subset, so a property `X` declares as required is present only after it has
910
+ * been written.
689
911
  *
690
- * The object is frozen and setExtendedValues is the way to change it: it is the object a transaction captured,
691
- * and one written in place would leave a rollback with nothing to put back.
912
+ * The object is frozen; change it with setExtendedValues. A transaction captures this object, so an in-place
913
+ * write would leave a rollback with no previous state to restore.
692
914
  */
693
915
  get extra(): Readonly<Partial<X>>;
694
916
  /**
695
- * Writes extended properties. The values given are merged over the ones the element carries, so a write of one
696
- * property leaves the others standing, and the merged set replaces the object the element held.
917
+ * Writes extended properties. The given values are merged over the existing ones, so a write of one property
918
+ * keeps the others, and the merged object replaces the one the element held.
697
919
  */
698
920
  setExtendedValues(values: Partial<X>): void;
699
921
  /**
700
- * The extended properties a parameter object carries: every key the element does not answer for itself. A key
701
- * the element answers for at the time the parameters are applied - `value`, `access`, an accessor a subclass
702
- * adds - is the element's own; a key that only Object.prototype answers for is nobody's declaration and counts
703
- * as extended, and `validators` and `actions` are neither, since they state what to register on the element.
922
+ * Returns the extended properties in a parameter object: every key that is not a member of the element. A key
923
+ * that is a member when the parameters are applied (`value`, `access`, an accessor a subclass adds) belongs to
924
+ * the element. A key that exists only on Object.prototype counts as extended. `validators` and `actions` are
925
+ * neither: they name what to register on the element.
704
926
  *
705
- * A member a subclass declares as a class field is not among the keys the element answers for: class fields are
706
- * defined on the instance after the base constructor returns, and the parameters are applied inside it. A
707
- * subclass that wants a parameter of its own name assigned to it declares that member as an accessor.
927
+ * A member a subclass declares as a class field is not a member at this point: class fields are defined on the
928
+ * instance after the base constructor returns, and the parameters are applied inside it. A subclass that needs a
929
+ * parameter assigned to a member of the same name declares that member as an accessor.
708
930
  */
709
931
  protected extendedOf(params: object): Partial<X>;
710
932
  /**
711
- * Applies a parameter object: the members the element answers for are assigned to the element and the rest
712
- * become its extended properties. Assigning a getter-only member throws a TypeError, which is what a caller
713
- * naming `valid` or `parent` past the type system gets.
933
+ * Applies a parameter object: a key that names an accessor of the element is assigned to the element, and every
934
+ * other key becomes an extended property. A key named like a method or another non-accessor member (`validate`,
935
+ * `bind`, `settled`) is stored in `extra` and leaves the member as it is. Assigning a getter-only accessor throws a
936
+ * TypeError, so a parameter object that bypasses the type system and contains `valid` or `parent` throws.
714
937
  */
715
938
  protected assignParams(params: object): void;
716
939
  /**
717
- * Takes this element into the record of the open transaction, where one is open. A write of a single slot that
718
- * announces nothing calls it instead of opening a transaction of its own: on its own such a write is already
719
- * atomic, and inside a transaction it has to be part of what a rollback puts back.
940
+ * Adds this element to the record of the open transaction, if one is open. A write of a single slot that announces
941
+ * nothing calls it instead of opening a transaction: outside a transaction such a write is atomic, and inside one
942
+ * it must be restored by a rollback.
720
943
  */
721
944
  protected touchState(): void;
722
945
  /**
723
- * Records the whole of this element's mutable state, so that a rolled-back transaction can put it back exactly
724
- * as it found it. The errors array is copied because a validator writes into the array it is handed rather than
725
- * replacing it, and a subclass copies whatever else it holds by reference the same way.
946
+ * Records all of this element's mutable state, so that a rolled-back transaction restores it exactly. The errors
947
+ * array is copied because a validator modifies the array in place, and a subclass copies any other state it holds
948
+ * by reference in the same way.
726
949
  *
727
- * What is not in the snapshot is the action map, which no write touches: an operation that replaces it hands
728
- * the transaction its own undo instead, so this stays the one shape every element captures.
950
+ * The action map is not in the snapshot: no write modifies it, and an operation that replaces it registers its
951
+ * own undo with the transaction, so every element captures the same shape.
729
952
  */
730
953
  protected [TxCapture](): TxSnapshot;
731
954
  /**
732
- * Puts a captured state back. It writes through the tracked view, so an effect that ran on the state the
733
- * transaction produced runs again on the state it is being returned to, and only for the slots that differ.
955
+ * Restores a captured state. It writes through the tracked view, so an effect that ran on the state the
956
+ * transaction produced runs again on the restored state, for the slots that differ.
734
957
  *
735
- * The two validation counters are the slots the element keeps: they count runs that are in flight, and a
736
- * rollback cannot un-start one. Put back, the counts would no longer match the endValidating calls still to come.
958
+ * The two validation counters are not restored: they count runs in flight. A rollback cancels the asynchronous
959
+ * runs the transaction started, and each cancelled run ends its count when its promise settles; restored counts
960
+ * would not match the endValidating calls still to come.
737
961
  */
738
962
  protected [TxRestore](snapshot: TxSnapshot): void;
739
963
  /**
740
- * True while an asynchronous validation is in flight on this element or on anything below it, so a form answers
741
- * for the whole tree it holds. The answer is a pair of counters rather than a walk: the element's own runs, and
742
- * how many of its children answer the same question with true. A child that starts running while it was idle,
743
- * or stops while it was the last one running, moves its container's tally, and a tally that changes the
744
- * container's own answer moves the one above it - the transition costs the nesting depth and the read costs
745
- * nothing.
964
+ * True while an asynchronous validation is in flight on this element or on any element below it, so on a form it
965
+ * covers the whole tree. It is computed from two counters, without a walk: the element's own runs, and the number
966
+ * of its children whose `validating` is true. A child that becomes validating or stops validating updates its
967
+ * container's counter, and a change of the container's `validating` updates the counter above it. A transition
968
+ * costs one step per nesting level; a read costs one counter comparison.
746
969
  */
747
970
  get validating(): boolean;
748
- /** announces the start of one asynchronous validation run; validators pair it with endValidating */
749
- beginValidating(): void;
750
- /** announces the end of one asynchronous validation run */
751
- endValidating(): void;
752
971
  /**
753
- * Records that a child started or stopped answering `validating` with true, and carries the transition further
754
- * up where it changes this element's own answer. Only a `Container` has children, and it implements this; it is
755
- * declared here because a child tells its container through it.
972
+ * Counts one asynchronous validation run as started and returns the function that counts it as ended. The
973
+ * function ends that run only: a second call does nothing, so `validating` and `settled()` cannot report the end
974
+ * of a run that is still in flight.
975
+ */
976
+ [BeginValidating](): () => void;
977
+ /**
978
+ * Records that a child's `validating` became true or false, and passes the transition up if it changes this
979
+ * element's own `validating`. Only a `Container` has children and implements this; it is declared here because a
980
+ * child calls it on its container.
756
981
  */
757
982
  protected childValidatingChanged(started: boolean): void;
758
983
  /**
759
- * True while an `Action.execute()` at or below this element has yet to settle. An `Action` answers for its own
760
- * runs; a container answers for the actions below it; anything else answers false, because an element that is
761
- * not an action has nothing to execute.
984
+ * True while an `Action.execute()` at or below this element has not settled. On an `Action` it covers its own
985
+ * runs, on a container the actions below it; on any other element it is false.
762
986
  *
763
- * It states one thing and `validating` states the other, so a form that gates a submit button on the tree being
764
- * idle reads both.
987
+ * It does not include validation; `pending` covers both.
765
988
  */
766
989
  get busy(): boolean;
767
990
  /**
768
- * Resolves once nothing at or below this element is running - no asynchronous validation, no `Action.execute()`
769
- * that has yet to settle. It is what a submit path awaits instead of polling `validating` and `busy`, and it
770
- * resolves at once where nothing is running to begin with.
991
+ * True while an asynchronous validation or an `Action.execute()` at or below this element has not settled:
992
+ * `validating || busy`. It is reactive, so a template binds a submit button to it. `settled()` resolves when it
993
+ * turns false.
994
+ */
995
+ get pending(): boolean;
996
+ /**
997
+ * Resolves when nothing at or below this element is running: no asynchronous validation and no unsettled
998
+ * `Action.execute()`, which is when `pending` is false. A submit path awaits it instead of polling `pending`. If
999
+ * nothing is running, the returned promise is already resolved.
771
1000
  *
772
- * It answers for the moment it resolves and makes no promise about the one after: work started later leaves the
773
- * element running again, so a caller that has to act on a settled tree reads what it needs immediately after
774
- * awaiting rather than at its leisure.
1001
+ * It covers only the moment it resolves: work started later makes the element run again, so a caller that needs
1002
+ * a settled tree reads what it needs immediately after the await.
775
1003
  */
776
1004
  settled(): Promise<void>;
777
1005
  /**
778
- * List of errors. The array handed out is the one the element holds, and a validator writes into it in place,
779
- * so a transaction that is open takes the element into its record here: a rollback that put back everything
780
- * except the errors would leave a state the form never held.
1006
+ * List of errors. The returned array is the one the element holds, and a validator modifies it in place, so this
1007
+ * getter adds the element to an open transaction's record: otherwise a rollback would restore everything except
1008
+ * the errors.
781
1009
  *
782
- * The array and its members are Vue proxies, not the raw instances a validator returned - `field.errors[0] ===
783
- * myError` is `false` for the very error that produced it. Unwrapping here would lose the tracked read a
784
- * template needs to re-render when a message behind a `Ref` changes; `toRaw()` compares identity instead.
1010
+ * The array and its members are Vue proxies, not the raw instances a validator returned: `field.errors[0] ===
1011
+ * myError` is `false` even for the same error. Compare identity with `toRaw()`.
1012
+ *
1013
+ * Whether an error of an origin other than `'validator'` counts toward `valid`, and when the element removes it
1014
+ * by itself, is the rule of its origin: see `ErrorPolicy`. An `'edit'` rule compares the value the element holds
1015
+ * against the one it held when the error was written: the value at the assignment of `errors`. For an error added
1016
+ * to the array in place it is the value at the next read of `errors` outside a transaction, and a change of the
1017
+ * element's value before that read counts as a change.
785
1018
  */
786
1019
  get errors(): ValidationError[];
787
1020
  set errors(newValue: ValidationError[]);
1021
+ /** Records the value the element holds as `errorsBaseline` where it holds a ruled error and has none recorded. */
1022
+ private noteErrorsBaseline;
1023
+ /**
1024
+ * The rule of `origin` for this element: the one stated by the nearest `ErrorPolicy` naming it, on this element or
1025
+ * on a container above it, and otherwise the default. The walk reads `parent` through the tracked view, so a
1026
+ * validity computed over it follows the element into another container.
1027
+ */
1028
+ private ruleOf;
1029
+ /** This element and every container above it, nearest first. */
1030
+ private selfAndAbove;
1031
+ /** Whether `errors`, held by this element, leave it valid: none of them counts toward validity. */
1032
+ protected ownErrorsValid(errors: readonly ValidationError[]): boolean;
1033
+ /**
1034
+ * Removes the ruled errors whose rule `removes` accepts and returns whether it removed any. The caller has added
1035
+ * the element to the transaction and recomputes its validity.
1036
+ */
1037
+ private removeErrors;
1038
+ /**
1039
+ * Called when `touched = true` is written on this element: on it and on every container above it, the errors whose
1040
+ * rule removes them on `'edit'` are removed where the element's value differs from the one recorded when they
1041
+ * were written.
1042
+ */
1043
+ protected editConcluded(): void;
1044
+ /** Removes, on this element and every element below it, the errors whose rule removes them on `'submit'`. */
1045
+ [RemoveErrorsOnSubmit](): void;
1046
+ /**
1047
+ * Recomputes the validity of every element at or below this one that holds a ruled error, after the rules over
1048
+ * those errors may have changed.
1049
+ */
1050
+ [ErrorPoliciesChanged](): void;
788
1051
  /**
789
1052
  * The container that holds this element: the Group it is a member of, or the List whose row it is, and
790
- * undefined while no container holds it. The container writes it; everyone else reads it. The read is tracked,
791
- * so an effect rendering off the link - `v-if="field.parent"` - re-runs when a container takes the element or
792
- * releases it.
1053
+ * undefined while no container holds it. Only the container writes it. The read is tracked, so an effect that
1054
+ * reads it (`v-if="field.parent"`) re-runs when a container takes or releases the element.
793
1055
  *
794
- * The type is `Container`, which names no members: a sibling lookup states which container it expects, either
795
- * with `field.parent instanceof Group` or with a cast where the structure guarantees it.
1056
+ * The type is `Container`, which declares no members: a sibling lookup narrows it, either with
1057
+ * `field.parent instanceof Group` or with a cast where the structure guarantees the type.
796
1058
  */
797
1059
  get parent(): Container | undefined;
798
1060
  /**
799
- * The same link at the type the internals reach through. The hooks a child tells its container things through -
800
- * childValidatingChanged, childValidityChanged - are declared here, and a protected member is reachable only
801
- * through the class that declares it; `Container` overrides them, so the link is read as a `FieldBase`.
1061
+ * The same link, typed as `FieldBase` for internal calls. The hooks a child calls on its container
1062
+ * (childValidatingChanged, childValidityChanged) are declared here, and a protected member is reachable only
1063
+ * through the class that declares it; `Container` overrides them.
802
1064
  */
803
1065
  private get container();
804
1066
  /** when member of a Group, fieldName specifies the name of this field. Written by the group, read-only after */
805
1067
  get fieldName(): string | undefined;
806
1068
  /**
807
1069
  * The element this one was declared as: itself for an element built from parameters, and the element it was
808
- * bound from for a binding - transitively, so a binding of a binding names the same one. Every row a `List`
809
- * builds from an item template is a binding of it, so a row's member and the template's member it stands for
810
- * answer with the same element, and an action registered on the template can tell the two apart.
1070
+ * bound from for a binding, transitively, so a binding of a binding has the same declaration. Every row a `List`
1071
+ * builds from its item template is a binding of it, so a row's member and the corresponding item template member
1072
+ * have the same `declaration`, and an action registered on the item template can distinguish the two.
811
1073
  */
812
1074
  get declaration(): FieldBase;
813
1075
  /** The elements this one holds: a Group's members, a List's rows, none for a leaf. */
814
1076
  protected get members(): FieldBase[];
815
1077
  /**
816
- * Every element in this element's subtree, this element included, that was declared as `declaration`. It answers
817
- * the question a shared action asks when the record it changed in is not the record its targets live in - a form
818
- * field that every row of a list reacts to - and it costs the subtree, so it is the path taken only when the
819
- * cheaper one, resolving within a single record, does not apply.
1078
+ * Returns every element in this element's subtree, this element included, whose declaration is `declaration`. A
1079
+ * shared action uses it when the change happened in a different record than its targets (a form field that every
1080
+ * row of a list reacts to). It walks the subtree, so it is used only when resolution within a single record does
1081
+ * not apply.
820
1082
  */
821
1083
  bindingsOf(declaration: FieldBase): FieldBase[];
822
1084
  /** set while an eager pass over this element is waiting for the record the element belongs to */
823
1085
  protected _recordPending?: boolean;
824
1086
  /**
825
- * States that an eager pass over this element reached an element it needs and did not find it, because the
826
- * record this element belongs to was not assembled at the time: a `List` row is built member by member and its
827
- * members are bound before any of them holds the row, so a validator comparing two of them runs before the
828
- * row exists. The container that finishes the record runs the pass again, and a pass that still reaches
829
- * nothing says so again, so the next container above answers for it.
1087
+ * Marks that an eager pass over this element did not find an element it needs, because the record this element
1088
+ * belongs to was not assembled yet: a `List` row is built member by member and its members are bound before the
1089
+ * row holds them, so a validator comparing two of them runs before the row exists. The container that completes
1090
+ * the record runs the pass again; a pass that still finds nothing marks the element again, and the next container
1091
+ * above runs it.
830
1092
  */
831
1093
  markRecordIncomplete(): void;
832
1094
  /**
833
- * Runs the eager passes outstanding in `element`'s subtree, now that the record it belongs to is assembled. A
834
- * container calls it where it has just made a record complete: a Group that has written its members, and a
835
- * List that has taken a row, which is what gives the row's fields the form above it.
1095
+ * Runs the pending eager passes in `element`'s subtree, once the record it belongs to is assembled. A container
1096
+ * calls it after it completes a record: a Group after it has written its members, and a List after it has taken a
1097
+ * row, which connects the row's elements to the form above it.
836
1098
  */
837
1099
  protected completeRecords(element?: FieldBase): void;
838
- /** Runs this element's eager actions over the value it holds and re-forms the verdict they reach. */
1100
+ /** Runs this element's eager actions over the value it holds and recomputes its validity. */
839
1101
  private rerunEagerActions;
840
1102
  /**
841
- * The map an element that was declared rather than bound registers its actions in, absent while it has registered
842
- * none. A binding holds no map of its own: `boundActions` reads the one its declaration holds.
1103
+ * The map of actions registered on a declaration; undefined until one is registered. A binding has no map of its
1104
+ * own: its slot holds the same map as its declaration.
843
1105
  */
844
1106
  protected _actions?: ActionsMap;
845
1107
  /**
846
- * The actions this element answers to, absent where nothing is registered. A binding holds the very map its
847
- * declaration holds rather than a copy of it, so the slot is read directly: what a trigger costs is one property
848
- * read, and a rule registered on a `List`'s item template reaches every row through the map they share - the
849
- * rows built before the registration as much as the ones built after.
1108
+ * The actions registered for this element; undefined if none are registered. A binding holds its declaration's
1109
+ * map itself, not a copy, so a trigger reads one property, and a rule registered on a `List`'s item template
1110
+ * reaches every row through the shared map, including rows built before the registration.
850
1111
  */
851
1112
  protected get boundActions(): ActionsMap | undefined;
852
1113
  /** Records that `binding` was made from this element, so a later registration can reach it. */
853
1114
  protected noteBinding(binding: FieldBase): void;
854
1115
  /**
855
- * The bindings made from this element that are still alive, and this element itself. The dead references are
856
- * dropped as they are found, which is what keeps the set from growing over the life of a long-lived declaration.
1116
+ * The live bindings made from this element's declaration, and the declaration itself. Dead references are removed
1117
+ * when found, so the set does not grow over the life of a long-lived declaration.
857
1118
  */
858
1119
  protected get boundElements(): FieldBase[];
859
1120
  /**
860
- * The map registrations go into: the declaration's, since that is where behaviour lives. The map is made on the
861
- * first registration and handed to every binding already made from the declaration, so all of them go on reading
862
- * one map through a slot of their own.
1121
+ * The map registrations go into: the declaration's. The map is created on the first registration and assigned to
1122
+ * every binding already made from the declaration, so all of them read one map through their own slot.
863
1123
  */
864
1124
  protected get actions(): ActionsMap;
865
1125
  /**
866
- * Counts the writes that have changed the value of this element or of anything below it. A container reads it
867
- * before answering from its value cache, and the read is an ordinary tracked one, so an effect that took a
868
- * cached value still re-runs when a descendant is written.
1126
+ * Counts the writes that have changed the value of this element or of any element below it. A container reads it
1127
+ * before returning its cached value, and the read is tracked, so an effect that read a cached value re-runs when
1128
+ * a descendant is written.
869
1129
  */
870
1130
  protected get valueVersion(): number;
871
1131
  /**
872
- * Marks the value of this element and of every ancestor as superseded. It walks the parent chain, so it costs
873
- * the nesting depth: an ancestor rebuilds its value the next time one is asked of it, instead of being walked
874
- * here for a reader that may never come. The walk also brings each element into the open transaction, so a
875
- * rollback puts the versions back and no reader is left holding a cache the tree no longer supports.
1132
+ * Marks the value of this element and of every ancestor as outdated. It walks the parent chain only (one step per
1133
+ * nesting level); an ancestor rebuilds its value on the next read. The walk adds each element to the open
1134
+ * transaction, so a rollback restores the versions and no cached value outlives the state it was built from.
876
1135
  */
877
1136
  protected bumpValueVersion(): void;
878
1137
  /**
879
- * States that this element's value changed and that every container above it therefore holds a different value
880
- * too. Nothing is announced here: the transaction works out at commit which of the elements enrolled actually
881
- * ends up holding a different value, and announces those once each.
1138
+ * Marks that this element's value changed, and with it the value of every container above it. Nothing is
1139
+ * announced here: at commit the transaction determines which enrolled elements hold a different value and
1140
+ * announces each of them once.
1141
+ *
1142
+ * Every value change of an element passes through here, so this is where the element removes the errors whose
1143
+ * rule removes them on `'change'`, and records that its value changed where it holds a ruled error with no value
1144
+ * recorded to compare against. The removal is part of the transaction and a rollback restores the errors.
882
1145
  *
883
- * `force` states that the caller already knows this element's value changed - one item more or fewer is a
884
- * different list whatever the items compare as - so the commit announces it without composing a comparison.
1146
+ * `force` means the caller has established that the value changed (a list with one item more or fewer is a
1147
+ * different list whatever the items compare as), so the commit announces it without a comparison.
885
1148
  */
886
1149
  protected propagateValueChanged(force?: boolean): void;
1150
+ /** What a change of the element's value does to its ruled errors; see `propagateValueChanged`. */
1151
+ private errorsAfterChange;
887
1152
  /**
888
- * The last step of a construction: it runs inside the transaction the construction is, with the parameters
889
- * applied and the value in place, before the element records what it was built as.
1153
+ * The last step of a construction: it runs inside the construction's transaction, with the parameters applied and
1154
+ * the value in place, before the element records its initial state.
890
1155
  *
891
- * A subclass overrides it to complete what the element was built with. What it writes here is part of the
892
- * construction rather than a change of it: the element announces no ValueChangedAction, and what the hook
893
- * leaves is what its eager actions and its validators run over, once. An element whose parameters named no
894
- * `originalValue` is baselined on the value the hook left and so starts unchanged; one that named a baseline is
895
- * measured against it, as any element is. A `Field` writes `_value`: the value setter states a change, and
896
- * this is not one.
1156
+ * A subclass overrides it to complete the element. What it writes here is part of the construction, not a
1157
+ * change: the element announces no ValueChangedAction, and its eager actions and validators run once over the
1158
+ * state the hook leaves. An element whose parameters contain no `originalValue` takes the value the hook left as
1159
+ * its `originalValue` and starts unchanged; one whose parameters contain `originalValue` is compared against it.
1160
+ * A `Field` writes `_value` here, because the value setter records a change.
897
1161
  *
898
- * A container completes itself through its members, and a member carries a construction of its own: the write
899
- * reaches it as any later one would, so the member announces it and reports itself changed. A member that is to
900
- * start unchanged is baselined here as well - `this.fields.x.originalValue = this.fields.x.value`.
1162
+ * A container completes itself through its members, and each member has already been constructed: the write
1163
+ * reaches it as a regular change, so the member announces it. A `Group` constructed with a value records what each
1164
+ * member holds after this hook as its baseline; without a value the member reports itself changed. To have a
1165
+ * member start unchanged in both cases, set its baseline here as well:
1166
+ * `this.fields.x.originalValue = this.fields.x.value`.
901
1167
  *
902
- * `params` is the parameter object the constructor received, where it received one.
1168
+ * `params` is the parameter object the constructor received, if any.
903
1169
  */
904
1170
  protected constructed(params?: object): void;
905
1171
  /**
906
- * Re-reads what the next announcements will report as replaced. A contribution is composed only where something
907
- * listens for it, so the copy is re-read here; a leaf records what it holds at every announcement, so that copy
908
- * is always current, and a container that skipped composing what nobody was listening for re-reads its own too.
1172
+ * Re-reads the old value the next announcements will report. A contribution is composed only when something
1173
+ * listens for it, so the stored copy is re-read here. A leaf records its value at every announcement, so that
1174
+ * copy is always current; a container, which composes its held value only for a listener, re-reads that too.
909
1175
  */
910
1176
  protected refreshPreviousValue(): void;
911
1177
  /**
912
- * The verdict validate() records and announces: this element's own errors plus the tally of children that
913
- * reported themselves invalid, so a container forms it without walking its members. `valid` is the read path
914
- * and answers over the live errors arrays instead; the two differ only for an error written into a member
915
- * without a validate() call, which is the documented cost of pushing errors by hand.
1178
+ * The validity validate() records and announces: computed from this element's own errors and the count of invalid
1179
+ * children, so a container computes it without walking its members. `valid` reads the live errors arrays instead;
1180
+ * the two differ only for an error written into a member without a validate() call, which is the documented
1181
+ * limitation of writing errors by hand.
916
1182
  */
917
1183
  protected get countedValid(): boolean;
918
1184
  /**
919
- * Makes this element the container of `child`: it installs the back-reference, records the name a Group holds
920
- * the child under, and takes the child into the invalid tally. An element belongs to one container at a time,
921
- * so a child that already carries the link is refused; releaseChild() takes the link away again, and an element
922
- * released that way can be handed on. The child's state is unreachable from outside FieldBase, so a container
923
- * writes the two slots through here rather than on the child.
1185
+ * Makes this element the container of `child`: it sets the back-reference, records the name a Group holds the
1186
+ * child under, and adds the child to the invalid count. An element belongs to one container at a time, so a
1187
+ * child that already has a parent throws a TypeError; releaseChild() removes the link, after which the element
1188
+ * can be taken by another container. The child's state is private to FieldBase, so a container writes the two
1189
+ * slots through this method.
924
1190
  */
925
1191
  protected takeChild(child: FieldBase, fieldName?: string): void;
926
- /** Takes a child into this element's invalid tally; a container calls it once the child's parent link exists. */
1192
+ /** Adds a child to this element's invalid count; a container calls it after setting the child's parent link. */
927
1193
  protected adoptChild(child: FieldBase): void;
928
1194
  /**
929
- * Drops a child out of this element's invalid tally and takes its back-reference away. An element keeps no link
930
- * to a container that no longer holds it: it would go on moving that container's tally, and the link is what
931
- * stands in the way of the element being taken by another container.
1195
+ * Removes a child from this element's invalid count and clears its back-reference. With the link left in place,
1196
+ * the element would keep updating that container's invalid count and could not be taken by another container.
932
1197
  */
933
1198
  protected releaseChild(child: FieldBase): void;
934
1199
  /**
935
- * Brings this element to the state a fresh binding of `source` carrying `value` would be in: `value` is written
936
- * where the caller supplied one and `source`'s own value where it did not, the change history - originalValue,
937
- * touched - starts over and the errors are dropped and re-established by the validators. A container that reuses
938
- * an element at a position it already holds calls it, so the element is indistinguishable from one built for
939
- * that position.
1200
+ * Sets this element to the state of a new binding of `source` with `value`: `value` is written if supplied, and
1201
+ * `source`'s value otherwise; the change history (originalValue, touched) starts over, and the errors are cleared
1202
+ * and set again by the validators. A container that reuses an element at a position calls it through
1203
+ * `resetChild`, which also writes the flags, inside `asReset`, which applies the rules before the baseline is
1204
+ * final, so the element is in the state of one built for that position; extended properties are kept.
940
1205
  */
941
1206
  protected resetTo(source: FieldBase, value: any): void;
942
- /** Resets a member. It is what lets a container reach the reset of a child whose class it does not know. */
1207
+ /**
1208
+ * Resets a member. A container calls it to reset a child of any class. A child reset from an element other than
1209
+ * itself (a member of a bound group, a reused `List` row) also takes `source`'s `access` and `visibility`, and its
1210
+ * eager actions run again once the record is complete, so the conditional rules apply over the new record. A child
1211
+ * that is its own source (a member of a declared group) keeps its flags.
1212
+ */
943
1213
  protected resetChild(child: FieldBase, source: FieldBase, value: any): void;
944
1214
  /**
945
- * Records a child's new verdict in this element's tally. Only a `Container` has children, and it implements
946
- * this; it is declared here for the reason `childValidatingChanged` is.
1215
+ * Runs `reset`, which resets elements to new records through `resetTo`, as one reset. Once every element holds
1216
+ * its new values, the rules of each reset element (its eager actions other than the validators) run over them, and
1217
+ * each records its baseline again, so `originalValue` includes what the rules changed: a member a conditional
1218
+ * access enables is in its container's baseline. A reset inside a reset is part of the outer one.
1219
+ */
1220
+ protected asReset(reset: () => void): void;
1221
+ /**
1222
+ * Records what every element below this one holds as its baseline, each after its own members. A binding, and a
1223
+ * group constructed with a value, call it once built, so a member written by the construction is not a change.
1224
+ */
1225
+ protected baselineMembers(): void;
1226
+ /**
1227
+ * Records what the element holds as its baseline at the end of a reset. A container also records it as the
1228
+ * value its listeners last heard: the container that reset it announces the change.
1229
+ */
1230
+ protected recordBaseline(): void;
1231
+ /**
1232
+ * Records a child's new validity in this element's invalid count. Only a `Container` has children and implements
1233
+ * this; it is declared here for the same reason as `childValidatingChanged`.
947
1234
  */
948
1235
  protected childValidityChanged(nowValid: boolean): void;
949
1236
  /**
950
- * How a rendering layer shows this element. It is presentation alone: what the element sends and whether it is
951
- * validated are its `access`, and no visibility changes either.
1237
+ * How a rendering layer shows this element. It affects presentation only: what the element sends and whether it
1238
+ * is validated are determined by `access`, and visibility changes neither.
952
1239
  */
953
1240
  get visibility(): Visibility;
954
1241
  set visibility(newValue: Visibility);
955
1242
  /**
956
1243
  * What this element accepts and what it sends: `'editable'` and `'readonly'` send its value, `'disabled'` sends
957
1244
  * nothing and `'disabled-null'` sends `null`, and only `'editable'` accepts input. The validators run over what
958
- * the element sends and only where it is sent at all, as `effectiveAccess` states, so a switch of access runs
959
- * them again here and below.
1245
+ * the element sends, and only where it is sent at all (see `effectiveAccess`), so a change of access that changes
1246
+ * what an element sends runs them again on that element, this one and the ones below it. A change between
1247
+ * `'editable'` and `'readonly'` changes what the element accepts, not what it sends, and runs nothing.
960
1248
  */
961
1249
  get access(): Access;
962
1250
  set access(newValue: Access);
963
1251
  /**
964
- * The access this element has once the containers above it are taken into account. A container that sends nothing
965
- * or `null` in place of what it holds sends none of its members, so below a `'disabled'` or `'disabled-null'`
966
- * container every element is `'disabled'`; below a `'readonly'` one an `'editable'` element is `'readonly'`.
967
- * Anywhere else it is the element's own access.
1252
+ * The access of this element after the containers above it are applied. A container that sends nothing or `null`
1253
+ * sends none of its members, so below a `'disabled'` or `'disabled-null'` container every element is
1254
+ * `'disabled'`; below a `'readonly'` one an `'editable'` element is `'readonly'`. Otherwise it is the element's
1255
+ * own access.
968
1256
  *
969
- * It is what decides whether the element's validators run: an element that is `'disabled'` here is sent nowhere,
970
- * so its validators reach no verdict and it carries none of their errors. Anywhere else they run over what the
971
- * element sends - its value, or `null`.
1257
+ * It determines whether the element's validators run: an element whose effective access is `'disabled'` is not
1258
+ * sent, so its validators produce no result and it has none of their errors. Otherwise they run over what the
1259
+ * element sends: its value, or `null`.
972
1260
  */
973
1261
  get effectiveAccess(): Access;
974
1262
  /**
975
- * Whether `effectiveAccess` is `'disabled'`, read off the untracked state. A validator asks it on every run, where
976
- * nothing renders off the answer and a tracked walk up the containers would cost every write a read per level.
1263
+ * Whether `effectiveAccess` is `'disabled'`, read from the untracked state. A validator reads it on every run,
1264
+ * where nothing renders from the result and a tracked walk up the containers would add a tracked read per level
1265
+ * to every write.
977
1266
  */
978
1267
  [SentNowhere](): boolean;
979
1268
  /**
980
- * True where `access` is `'editable'`: the element accepts input. It reads `access` and nothing else, and it is a
981
- * statement about input rather than about data - `'readonly'` is not enabled and still sends its value. What an
982
- * element sends is read from `access`.
1269
+ * True if `access` is `'editable'`: the element accepts input. It reads only `access` and concerns input, not
1270
+ * data: a `'readonly'` element is not enabled and still sends its value. What an element sends is read from
1271
+ * `access`.
983
1272
  */
984
1273
  get enabled(): boolean;
985
1274
  /**
986
- * True where `effectiveAccess` is `'editable'`: this element and every container above it accept input. A
987
- * rendering layer binds one read instead of walking the parent chain: a container that is not editable states
988
- * that its section cannot be edited, and the inputs rendered from the members inside it read that here.
1275
+ * True if `effectiveAccess` is `'editable'`: this element and every container above it accept input. A rendering
1276
+ * layer reads this instead of walking the parent chain; the inputs of members inside a container that is not
1277
+ * editable read false here.
989
1278
  */
990
1279
  get effectiveEnabled(): boolean;
991
1280
  /** The effective access of this element and of every element below it, read before a change that may move it. */
@@ -993,120 +1282,125 @@ export declare abstract class FieldBase<T = any, X extends object = Extras> {
993
1282
  /** The effective access of every element below this one, read before a change that may move it. */
994
1283
  private effectiveAccessBelow;
995
1284
  /**
996
- * Runs the validators again on every element whose effective access moved since `before` was read: one that stops
997
- * being sent drops their errors, and one that starts being sent is checked over what it now sends.
1285
+ * Runs the validators again on every element whose effective access changed what it sends since `before` was
1286
+ * read: an element that is no longer sent loses their errors, and one that is now sent is validated over what it
1287
+ * sends.
998
1288
  */
999
1289
  private revalidateWhereChanged;
1000
1290
  /**
1001
- * What this element contributes to its container's `value` or `fullValue`: its own value, `null` in its place, or
1002
- * nothing. It is the one place the rule is stated - every container composes its values by asking it.
1291
+ * What this element sends to its container's `value` or `fullValue`: its own value, `null`, or nothing. Every
1292
+ * container composes its values through this method.
1003
1293
  *
1004
- * `fullValue` states everything the form holds, so every element contributes its value there. `value` states
1005
- * what the form sends, and `access` decides it: `'disabled'` leaves the element out and `'disabled-null'` sends
1006
- * `null`, whatever a container holds below it.
1294
+ * `fullValue` contains everything the form holds, so every element sends its value there. `value` contains what
1295
+ * the form sends, determined by `access`: `'disabled'` omits the element and `'disabled-null'` sends `null`,
1296
+ * whatever a container holds below it.
1007
1297
  */
1008
1298
  protected serializesAs(purpose: 'value' | 'fullValue'): 'value' | 'null' | 'omit';
1009
- /** What `child` contributes to this container, asked the way `childComposesValue` asks what it is. */
1299
+ /** What `child` sends to this container; a protected-access bridge like `childComposesValue`. */
1010
1300
  protected childSerializesAs(child: FieldBase, purpose: 'value' | 'fullValue'): 'value' | 'null' | 'omit';
1011
1301
  /**
1012
1302
  * What this element sends to its container's `value`: its value where its access sends it, `null` for
1013
- * `'disabled-null'`, and `undefined` for `'disabled'`, whose key or row is left out. It is what the element's
1014
- * validators run over and what `ContributionChangedAction` reports.
1303
+ * `'disabled-null'`, and `undefined` for `'disabled'`, whose key or row is omitted. The element's validators run
1304
+ * over it, and `ContributionChangedAction` reports it.
1015
1305
  */
1016
1306
  get contribution(): unknown;
1017
1307
  /**
1018
- * What `ValueChangedAction` reports this element as holding: its value. A container holds every member's value
1019
- * whatever the member sends, so it answers with its `fullValue`.
1308
+ * The value `ValueChangedAction` reports for this element: its value. A container holds every member's value
1309
+ * whatever the member sends, so on a container it is its `fullValue`.
1020
1310
  */
1021
1311
  protected get holding(): any;
1022
1312
  /**
1023
- * Whether the container holding this element counts its verdict: every element that sends something, `null`
1024
- * included. A `'disabled'` element sends nothing, so it is not counted - an error written into it by hand no more
1025
- * than one from a validator, which does not run there.
1313
+ * Whether the container holding this element counts its validity: true for every element that sends something,
1314
+ * `null` included. A `'disabled'` element sends nothing, so it is not counted, neither for an error written by
1315
+ * hand nor for one from a validator (validators do not run on it).
1026
1316
  */
1027
1317
  private get countsInContainer();
1028
1318
  /**
1029
- * Carries a change of what this element sends: the element is enrolled so the commit measures its contribution
1030
- * and re-forms its verdict, the container's value is built again, and an element that is invalid enters or leaves
1031
- * the container's tally as it starts or stops being counted.
1319
+ * Processes a change of what this element sends: the element is enrolled so the commit compares its contribution
1320
+ * and recomputes its validity, the container's value is rebuilt, and an invalid element is added to or removed
1321
+ * from the container's invalid count as it starts or stops being counted.
1032
1322
  */
1033
1323
  private contributionChanged;
1034
1324
  /**
1035
- * True for an element whose value is composed of its members'. The commit builds such a value only where
1036
- * something receives it, compares it by content rather than by identity, and runs the element's own validators
1037
- * with the announcement: a container's validators read the composed value, which exists only once the members
1038
- * have been written. A leaf's validators have run at the write instead, so its announcement carries no eager
1039
- * pass of its own.
1325
+ * True for an element whose value is composed of its members' values. The commit builds such a value only if
1326
+ * something receives it, compares it by content (not identity), and runs the element's own validators with the
1327
+ * announcement: a container's validators read the composed value, which exists only after the members have been
1328
+ * written. A leaf's validators run at the write, so its announcement runs no eager pass.
1040
1329
  */
1041
1330
  protected get composesValue(): boolean;
1042
1331
  /**
1043
- * Whether `child` composes its value from members of its own. It is what lets a container tell a nested
1044
- * container from a leaf without knowing the classes below it, the way `resetChild` reaches a reset it does not
1045
- * know the shape of.
1332
+ * Whether `child` composes its value from its own members. A container uses it to distinguish a nested container
1333
+ * from a leaf without knowing the child's class, as with `resetChild`.
1046
1334
  */
1047
1335
  protected childComposesValue(child: FieldBase): boolean;
1048
1336
  /**
1049
- * Announces what this element holds and what it sends, as they became over the transaction. Each pair carried is
1050
- * (now, at the last announcement), so a value that went A -> B -> A within the transaction says nothing, and the
1051
- * events an operation states rather than an element's state - an item added, an item removed - are emitted first,
1052
- * in the order the operations happened.
1337
+ * Announces what this element holds and what it sends at the end of the transaction. Each pair is (now, at the
1338
+ * last announcement), so a value that went A -> B -> A within the transaction is not announced. Events that
1339
+ * describe an operation (an item added, an item removed) are emitted first, in the order the operations happened.
1053
1340
  *
1054
- * A container's validators read what it sends, which is composed here and nowhere else, so they run first, where
1055
- * that moved; a leaf's have run at the write. `ValueChangedAction` reports what the element holds, and
1056
- * `ContributionChangedAction` what it sends to its container.
1341
+ * A container's validators read what it sends, which is composed here, so they run first, if it changed; a
1342
+ * leaf's ran at the write. `ValueChangedAction` reports what the element holds, and `ContributionChangedAction`
1343
+ * what it sends to its container.
1057
1344
  */
1058
1345
  protected [TxAnnounceValue](tx: Transaction, dirty: boolean, force: boolean, structural?: TxStructuralEvent[]): void;
1059
1346
  /**
1060
- * Records what this element holds and sends as what was last announced, so the commit that follows reports no
1061
- * change of either. A construction calls it over the state it ends on, and so does an element brought to the
1062
- * state a fresh binding would be in.
1347
+ * Records what this element holds and sends as last announced, so the following commit announces no change of
1348
+ * either. A construction calls it over its final state, as does `rebind()`.
1063
1349
  */
1064
1350
  protected recordAnnounced(): void;
1065
1351
  /**
1066
- * Forms the verdict this element ends the transaction with and announces a transition of it. The container is
1067
- * told first, so a handler reads a tally that already includes this verdict, and it is enrolled in the same
1068
- * transaction: its own verdict is composed of its members', so a member that moves without a value change - an
1069
- * asynchronous validator, an error pushed in by hand - is what makes the container re-form its own. The
1070
- * transaction settles the deepest element first, so a container is reached only once its members have decided.
1352
+ * Computes the validity this element ends the transaction with and announces a change of it. The container is
1353
+ * updated first, so a handler reads an invalid count that already includes this element, and the container is
1354
+ * enrolled in the same transaction: its validity depends on its members', so a member whose validity changes
1355
+ * without a value change (an asynchronous validator, an error written by hand) makes the container recompute its
1356
+ * own. The transaction settles the deepest element first, so a container is settled after its members.
1357
+ */
1358
+ /**
1359
+ * Announces the net change of access, enabled and visibility over the transaction: `AccessChangedAction` and
1360
+ * `EnabledChangedAction` where the access differs from the one before the transaction's first write of it, and
1361
+ * `VisibilityChangedAction` likewise. A value that went back to where it started announces nothing.
1071
1362
  */
1363
+ protected [TxAnnounceFlags](): void;
1072
1364
  protected [TxSettleValidity](tx: Transaction): void;
1073
1365
  validate(revalidate?: boolean): void;
1366
+ /**
1367
+ * True while no error of the element counts toward validity: every error of origin `'validator'` counts, and an
1368
+ * error of another origin counts where its rule's `validEffect` is true (see `ErrorPolicy`).
1369
+ */
1074
1370
  get valid(): boolean;
1075
1371
  get fullValue(): T;
1076
1372
  get isChanged(): boolean;
1077
1373
  /**
1078
- * Brings a fresh element into the state a binding of `source` is in: it records what it was declared as, takes
1079
- * on the extended properties and the actions `source` carries, and runs the eager ones over the value it was
1080
- * built with. The extended properties `overrides` states are written over the ones `source` carries, and they
1081
- * are in place before the eager pass, so an action reading one sees what the binding ends up carrying. The
1082
- * actions are the very instances `source` holds - what a binding takes on is data, not behaviour - and each is
1083
- * told about this element as it is taken on, so an action serving several bindings knows all of them.
1374
+ * Sets up a new element as a binding of `source`: it records the declaration, copies the extended properties of
1375
+ * `source`, uses the actions `source` has, and runs the eager ones over the value it was built with. Extended
1376
+ * properties in `overrides` are written over the copied ones before the eager pass, so an action that reads one
1377
+ * sees the binding's final value. The actions are the same instances `source` holds, and each is bound to this
1378
+ * element (`boundToBinding`), so an action serving several bindings has a reference to each of them.
1084
1379
  */
1085
1380
  protected boundFrom(source: FieldBase<any, X>, newValue: any, oldValue: any, overrides?: object): void;
1086
1381
  /**
1087
- * Registers the actions a constructor received in its parameters: registration without the eager trigger,
1088
- * because a constructor ends with a single this.actions.triggerEager(...) over the finished value, and an
1089
- * eager action registered here would otherwise also run once per registration, over a half-built field.
1382
+ * Registers the actions a constructor received in its parameters, without the eager trigger: a constructor ends
1383
+ * with a single this.actions.triggerEager(...) over the finished value. With the trigger, an eager action would
1384
+ * also run once per registration, over a partially built field.
1090
1385
  */
1091
1386
  protected registerInitialActions(actions: FieldActionBase[]): void;
1092
1387
  registerAction(action: FieldActionBase): this;
1093
1388
  /**
1094
- * Registers `action` so that `before` wraps it: `before` reaches it through the `supr` it is handed, instead of
1095
- * ending the run there. It is how an action is added to a chain someone else built and still sits inside a
1096
- * handler already registered, which registration order alone cannot arrange. `before` has to be registered on
1097
- * this element under the same identifier.
1389
+ * Registers `action` so that `before` wraps it: `before` calls it through the `supr` argument. This adds an
1390
+ * action to an existing chain inside a handler that is already registered, which registration order alone cannot
1391
+ * do. `before` must be registered on this element under the same identifier.
1098
1392
  */
1099
1393
  registerActionBefore(action: FieldActionBase, before: FieldActionBase): this;
1100
1394
  /**
1101
- * Drops `action` from this element and answers whether it held it. The instance goes on serving every other
1102
- * element it was registered on: what is dropped is this element's registration, not the action. A validator
1103
- * withdraws the errors it put on this element as it goes, so the verdict the element reports is the one the
1104
- * validators it still holds reach.
1395
+ * Unregisters `action` from this element and returns whether it was registered. The registration is shared with
1396
+ * the element's declaration and every binding made from it, so the action is removed from all of them; elements
1397
+ * of other declarations that the same instance is registered on keep it. A validator removes the errors it put on
1398
+ * the elements it is removed from, so their validity reflects only the remaining validators.
1105
1399
  */
1106
1400
  unregisterAction(action: FieldActionBase): boolean;
1107
1401
  /**
1108
- * Records that `action` is now registered on this element, and that a rollback has to take that back. The
1109
- * registration is not one of the state slots the snapshot covers, so it hands its own undo in.
1402
+ * Binds a newly registered `action` to the existing bindings and registers an undo for a rollback. The
1403
+ * registration is not in the state slots the snapshot covers, so it registers its own undo.
1110
1404
  */
1111
1405
  private registered;
1112
1406
  triggerAction<T2 extends FieldActionBase>(actionClass: (abstract new (...args: any[]) => T2) & {
@@ -1117,7 +1411,7 @@ export declare abstract class FieldBase<T = any, X extends object = Extras> {
1117
1411
  * a result whose epoch no longer matches, so a validation still in flight when clearValidators() is called
1118
1412
  * cannot push an error onto a field that no longer has the validator that produced it.
1119
1413
  */
1120
- get validationEpoch(): number;
1414
+ get [ValidationEpoch](): number;
1121
1415
  clearValidators(): void;
1122
1416
  }
1123
1417
 
@@ -1128,23 +1422,23 @@ declare interface FieldSlots<T = any> extends ElementSlots<T> {
1128
1422
  }
1129
1423
 
1130
1424
  /**
1131
- * What Group.fullValue reads back. The indexed access reads each field's fullValue getter, so a nested group
1132
- * contributes its own full structure rather than the partial one its `value` builds. Every member is present
1133
- * whatever its access.
1425
+ * The type of Group.fullValue. The indexed access reads each element's fullValue getter, so a nested group has its
1426
+ * full structure, not the partial one its `value` builds. Every member is present whatever its access, except an
1427
+ * `Action`, which holds no data.
1134
1428
  */
1135
1429
  export declare type FieldsToFullValues<T extends GenericFieldsInterface> = {
1136
- [K in keyof T]: T[K]['fullValue'];
1430
+ [K in DataKeys<T>]: T[K]['fullValue'];
1137
1431
  };
1138
1432
 
1139
1433
  /**
1140
- * Converts a field structure into the matching value structure. The indexed access reads each field's value
1141
- * getter, so a nested Group contributes its own value structure and a List contributes its row array; inferring
1142
- * from FieldBase<infer U> instead would pick up the value setter, which is deliberately wider than the getter on
1143
- * Group. Every member may be `null`, because a member whose access is `'disabled-null'` contributes `null` in place
1144
- * of its value.
1434
+ * Converts a field structure into the matching value structure. The indexed access reads each element's value
1435
+ * getter, so a nested Group sends its own value structure and a List sends its row array; inferring from
1436
+ * FieldBase<infer U> would use the value setter, which on Group accepts a wider type than the getter returns.
1437
+ * Every member may be `null`, because a member whose access is `'disabled-null'` sends `null` in place of its
1438
+ * value. An `Action` member sends nothing and has no key.
1145
1439
  */
1146
1440
  export declare type FieldsToValues<T extends GenericFieldsInterface> = {
1147
- [K in keyof T]: T[K]['value'] | null;
1441
+ [K in DataKeys<T>]: T[K]['value'] | null;
1148
1442
  };
1149
1443
 
1150
1444
  declare namespace Form {
@@ -1157,6 +1451,15 @@ declare namespace Form {
1157
1451
  visibilityValues,
1158
1452
  defaultVisibility,
1159
1453
  isVisibility,
1454
+ configureDevtools,
1455
+ describeState,
1456
+ DevtoolsOptions,
1457
+ DevtoolsRegistration,
1458
+ hideState,
1459
+ StateDescription,
1460
+ installPlugin,
1461
+ Plugin_2 as Plugin,
1462
+ PluginContext,
1160
1463
  transaction,
1161
1464
  TransactionControl,
1162
1465
  FieldActionBase,
@@ -1167,6 +1470,16 @@ declare namespace Form {
1167
1470
  EnabledChangedAction,
1168
1471
  EnabledChangingAction,
1169
1472
  ExecuteAction,
1473
+ RejectAction,
1474
+ CommandTarget,
1475
+ SubmitAction,
1476
+ CommandException,
1477
+ SubmitFailedException,
1478
+ SubmitRefusalReason,
1479
+ SubmitRefusedException,
1480
+ SubmitOptions,
1481
+ SubmitResult,
1482
+ TargetedExecuteAction,
1170
1483
  VisibilityChangedAction,
1171
1484
  VisibilityChangingAction,
1172
1485
  ValidChangedAction,
@@ -1183,7 +1496,6 @@ declare namespace Form {
1183
1496
  ActionValue,
1184
1497
  Action,
1185
1498
  NullableAction,
1186
- MessagesWidget,
1187
1499
  Container,
1188
1500
  Field,
1189
1501
  NullableField,
@@ -1206,54 +1518,27 @@ declare namespace Form {
1206
1518
  ListValue,
1207
1519
  ListValueInput,
1208
1520
  ListFullValue,
1521
+ ListItemInput,
1209
1522
  List,
1210
1523
  NullableList,
1524
+ ErrorPolicies,
1525
+ ErrorPolicy,
1526
+ ErrorPolicyRule,
1527
+ ErrorRemoval,
1528
+ errorRemovals,
1529
+ setDefaultErrorPolicies,
1211
1530
  Validators,
1212
- buildErrorMessage,
1213
- translatedMessage,
1214
- strings,
1215
- translateStrings,
1216
- isSimpleComponentDef,
1217
- isCallableFunction,
1218
- MdString,
1219
- SimpleComponentDef,
1220
- ClassType,
1221
- ClassTypes,
1222
- RenderContentNonCallable,
1223
- RenderContentCallable,
1224
- RenderContent,
1225
- RenderContentRef,
1226
1531
  ErrorOrigin,
1532
+ ErrorDescription,
1227
1533
  ValidationError,
1228
- ValidationErrorText,
1229
- ValidationErrorRenderContent,
1230
- RenderableValue,
1231
1534
  view,
1232
1535
  View
1233
1536
  }
1234
1537
  }
1235
1538
  export default Form;
1236
1539
 
1237
- export declare const forms: {
1238
- install(app: any, options?: Partial<FormsConfig>): void;
1239
- };
1240
-
1241
- /**
1242
- * Global configuration for @dynamicforms/vue-forms.
1243
- *
1244
- * The configuration is module-global: `setConfig` and the plugin's `install` write the single record this module
1245
- * holds, so in a process running several Vue apps the configuration applied last is the one all of them read.
1246
- */
1247
- export declare interface FormsConfig {
1248
- /** Whether the built-in validators phrase their error messages as `MdString` markdown instead of plain text. */
1249
- useMarkdownInValidators: boolean;
1250
- }
1251
-
1252
1540
  export declare type GenericFieldsInterface = Record<string, FieldBase>;
1253
1541
 
1254
- /** The current configuration. The object is the module's own record, and reading it again reports later writes. */
1255
- export declare function getConfig(): FormsConfig;
1256
-
1257
1542
  export declare class Group<T extends GenericFieldsInterface = GenericFieldsInterface, X extends object = Extras> extends Container<GroupValue<T>, X> {
1258
1543
  get [Symbol.toStringTag](): string;
1259
1544
  protected get state(): GroupSlots<GroupValue<T>>;
@@ -1261,90 +1546,106 @@ export declare class Group<T extends GenericFieldsInterface = GenericFieldsInter
1261
1546
  private readonly _fields;
1262
1547
  constructor(fields: T, params?: IFieldParams<GroupValueInput<T>, X>);
1263
1548
  /**
1264
- * The name array is copied as well: a rollback puts back the set of members the group held, not the array it
1265
- * went on to hold.
1549
+ * Gives every member `data` contains its part of `data` as its baseline, and so on through the groups below it;
1550
+ * null gives each member null.
1551
+ */
1552
+ private baselineMembersFrom;
1553
+ /**
1554
+ * The name array is copied as well, so a rollback restores the set of members the group held before the
1555
+ * transaction.
1266
1556
  */
1267
1557
  protected [TxCapture](): TxSnapshot;
1268
1558
  /**
1269
- * The copy of a built value that serves as a baseline. The value getter hands out one object per version, and
1270
- * a baseline holding that same object would report every value as its own original.
1559
+ * A copy of a built value, used as a baseline. The value getter returns one object per version, and a baseline
1560
+ * holding that same object would make every value equal to its original.
1271
1561
  */
1272
1562
  private static baseline;
1273
1563
  /**
1274
- * Takes `field` into this group under `fieldName`. The group ends up holding it exactly as it holds a field the
1275
- * constructor was given: the field carries the back-reference and the name, its verdict counts towards the
1276
- * group's, and a rule of the field's that names another member of the form reaches it here.
1564
+ * Adds `field` to this group under `fieldName`, in the same state as an element passed to the constructor: the
1565
+ * element has the back-reference and the name, its validity counts towards the group's, and a rule of the element
1566
+ * that refers to another element of the form is resolved here.
1277
1567
  *
1278
- * The change is announced through the ordinary path, so a group whose value the new field adds to says so once
1279
- * the transaction closes, and its verdict is re-formed over the members it now holds. The baseline behind
1280
- * `isChanged` is not rewritten: a group that gains a field holds something its original value does not carry,
1281
- * and reports itself changed until `originalValue` is written.
1568
+ * The change is announced through the regular path: the group announces its new value when the transaction
1569
+ * closes, and its validity is recomputed over its current members. The baseline behind `isChanged` is not
1570
+ * rewritten: a group that gains an element holds a value its original value does not contain, and reports itself
1571
+ * changed until `originalValue` is written.
1282
1572
  *
1283
- * @throws Error where this group already holds a field under `fieldName`.
1284
- * @throws TypeError where `field` already belongs to a container - pass a `bind()` of it instead.
1573
+ * @throws Error if this group already holds an element under `fieldName`.
1574
+ * @throws TypeError if `field` already belongs to a container; pass a `bind()` of it instead.
1285
1575
  */
1286
1576
  addField(fieldName: string, field: FieldBase): this;
1287
1577
  /**
1288
- * Takes the field held under `fieldName` out of this group and hands it back, answering undefined where the
1289
- * group holds no field of that name. The field is released whole: the back-reference and the name are gone, its
1290
- * verdict and its runs in flight no longer count towards the group's, and it is free to be taken by another
1291
- * container. What it holds - its value, its errors, the change history behind `isChanged` - is its own to report.
1578
+ * Removes the element held under `fieldName` from this group and returns it, or returns undefined if the group
1579
+ * holds no element of that name. The back-reference and the name are cleared, its validity and its runs in
1580
+ * flight no longer count towards the group's, and another container can take it. It keeps its value, its errors
1581
+ * and the change history behind `isChanged`.
1292
1582
  *
1293
- * The change is announced through the ordinary path, so the group's value and verdict settle over the members it
1294
- * has left. The baseline behind `isChanged` is not rewritten, the same way it is not on `addField`.
1583
+ * The change is announced through the regular path, so the group's value and validity are recomputed over the
1584
+ * remaining members. The baseline behind `isChanged` is not rewritten, as with `addField`.
1295
1585
  */
1296
1586
  removeField(fieldName: string): FieldBase | undefined;
1297
1587
  /**
1298
- * Writes one entry of the member map. The map is typed by the fields interface, which names the members a group
1299
- * of that type holds and no others, so both here and in dropEntry it is reached as the plain record it is.
1588
+ * Writes one entry of the member map. The map is typed by the fields interface, which lists only the members of
1589
+ * that group type, so here and in dropEntry it is cast to a plain record.
1300
1590
  */
1301
1591
  private static setEntry;
1302
- /** Drops one entry out of the member map. */
1592
+ /** Removes one entry from the member map. */
1303
1593
  private static dropEntry;
1304
1594
  private static isValidFields;
1595
+ /**
1596
+ * Builds a group from plain data, so that its `fullValue` is `data`: a plain object becomes a `Group`, an array a
1597
+ * `List` without an item template (whose rows are built by the same rule), and any other value a `Field`, at every
1598
+ * level.
1599
+ */
1305
1600
  static createFromFormData(data: Record<string, any> | null): Group;
1306
1601
  field<K extends keyof T>(fieldName: K): T[K] | null;
1307
1602
  /**
1308
- * The typed map of this group's members. What it hands out is a view over the map the group holds: reading it
1309
- * reaches the members themselves, and every write to it is refused - addField() and removeField() are what
1310
- * change the set. The view is built the first time something asks for it.
1603
+ * The typed map of this group's members. It is a view over the map the group holds: a read returns the members
1604
+ * themselves, and every write throws a TypeError (use addField() and removeField()). The view is created on the
1605
+ * first read.
1311
1606
  *
1312
- * Reading through it is a tracked read of the set of members, so a template rendering off `group.fields`
1313
- * re-renders when a field is added or removed; what a member itself holds is tracked by that member.
1607
+ * A read through it is a tracked read of the set of members, so a template that reads `group.fields` re-renders
1608
+ * when an element is added or removed; each member tracks its own state.
1314
1609
  */
1315
1610
  get fields(): T;
1316
1611
  protected get members(): FieldBase[];
1317
1612
  protected get children(): readonly FieldBase[];
1318
1613
  get value(): GroupValue<T>;
1319
1614
  /**
1320
- * Writes the members that the given value carries. The members are written one by one and the group says
1321
- * nothing in between: the transaction the assignment runs in measures the group's own value and its own verdict
1322
- * once, over the finished set, and announces each at most once.
1615
+ * Writes the members whose keys the given value contains. The members are written one by one and the group
1616
+ * announces nothing in between: the transaction compares the group's value and validity once, after all members
1617
+ * are written, and announces each at most once.
1323
1618
  */
1324
1619
  private assignMembers;
1325
1620
  set value(newValue: GroupValueInput<T>);
1326
1621
  /**
1327
- * Members are reset one by one rather than assigned as a whole value: the value setter writes only the keys the
1328
- * value carries, while a member the value leaves out has to end up holding what the template gives it. `source`
1329
- * supplies that per member, so a group reset from the template it was bound from matches a fresh binding of it.
1622
+ * Members are reset one by one, not assigned as a whole value: the value setter writes only the keys the value
1623
+ * contains, while a member missing from the value must take its value from `source`. `source` supplies it per
1624
+ * member, so a group reset from the declaration it was bound from matches a new binding of it.
1330
1625
  */
1331
1626
  protected resetTo(source: FieldBase, value: any): void;
1627
+ protected recordBaseline(): void;
1332
1628
  /**
1333
- * Everything the group holds: every member's `fullValue`, whatever the member's access. Where `value` states what
1334
- * the group sends, this states what it holds, and it is what a binding of the group carries.
1629
+ * Everything the group holds: every member's `fullValue`, whatever the member's access. `value` is what the group
1630
+ * sends; `fullValue` is what it holds, and a binding of the group copies it.
1335
1631
  */
1336
1632
  get fullValue(): FieldsToFullValues<T>;
1337
1633
  /**
1338
- * States that `res` was built from the members handed to it. A subclass whose constructor takes something other
1339
- * than `(fields, params)` - one that composes its own members and passes them to super - never sees them, and
1340
- * would answer with a binding carrying the declaration's data instead of the record's. That is a difference no
1341
- * reader would find, so it is refused here rather than returned.
1634
+ * Throws a TypeError if `res` was not built from the members passed to it. A subclass whose constructor does not
1635
+ * take `(fields, params)` (one that composes its own members and passes them to super) ignores them and would
1636
+ * return a binding with the declaration's data instead of the record's. The difference would not be visible, so
1637
+ * it throws here.
1342
1638
  */
1343
1639
  private static assertTookFields;
1344
1640
  bind(data?: GroupValueInput<T>, overrides?: IBindParams<GroupValueInput<T>, X>): Group<T, X>;
1345
1641
  /**
1346
- * A record need not name every member: a key it leaves out is taken from the declaration, the same way a member
1347
- * the constructor is given no value for takes the one it was declared with.
1642
+ * `data` with every key it leaves out filled in with the baseline of the corresponding member, as `rebind` fills
1643
+ * it; null and an action, which holds no data, stay as they are.
1644
+ */
1645
+ private withBaselines;
1646
+ /**
1647
+ * A record need not contain every member: a member whose key is missing takes the `originalValue` of the
1648
+ * corresponding member of the group's declaration, and for a group that is its own declaration, its own baseline.
1348
1649
  */
1349
1650
  rebind(data: GroupValueInput<T>): this;
1350
1651
  }
@@ -1356,30 +1657,32 @@ declare type GroupData<F extends GenericFieldsInterface> = {
1356
1657
  -readonly [K in keyof F as F[K] extends Container ? never : K]: Slot<F[K]>;
1357
1658
  };
1358
1659
 
1359
- /** what a Group holds beyond the container slots: the names of its members, in the order it took them */
1660
+ /** what a Group holds beyond the container slots: the names of its members, in the order they were added */
1360
1661
  declare interface GroupSlots<T = any> extends ContainerSlots<T> {
1361
1662
  /**
1362
- * The names the group holds its members under. The member map itself is a plain object beside the state, so
1363
- * this array is what a reader inside an effect depends on: a member added or removed re-runs the effect, and a
1364
- * rolled-back transaction puts the set back with the rest of the slots.
1663
+ * The names the group holds its members under. The member map is a plain object outside the reactive state, so
1664
+ * a reader inside an effect depends on this array: adding or removing a member re-runs the effect, and a rollback
1665
+ * restores the names with the other slots.
1365
1666
  */
1366
1667
  fieldNames: string[];
1367
1668
  }
1368
1669
 
1369
1670
  /**
1370
- * What Group.value reads back: the values of the members that serialize, and `{}` where none does. Every key is
1371
- * optional, because a member whose access is `'disabled'` is left out of the object the group builds.
1671
+ * The type of Group.value: the values of the members that send something, and `{}` if none does. Every key is
1672
+ * optional, because a member whose access is `'disabled'` is omitted from the object the group builds.
1372
1673
  */
1373
1674
  export declare type GroupValue<T extends GenericFieldsInterface> = Partial<FieldsToValues<T>>;
1374
1675
 
1375
- /** what Group.value and the Group constructor accept: keys left out are simply not assigned, and null clears */
1676
+ /** what Group.value and the Group constructor accept: missing keys are not assigned, and null clears */
1376
1677
  export declare type GroupValueInput<T extends GenericFieldsInterface> = Partial<FieldsToValues<T>> | null;
1377
1678
 
1679
+ /** Leaves `element` out of the devtools, or lists it again with `hidden` false. Does nothing in production. */
1680
+ export declare function hideState(element: FieldBase, hidden?: boolean): void;
1681
+
1378
1682
  /**
1379
- * What bind() accepts beside the data it binds: the three members a binding takes over from the element it was
1380
- * bound from, and the extended properties. What is left out is left out because a binding cannot honour it -
1381
- * `validators` and `actions` are carried from the declaration rather than supplied, and `touched` and `errors`
1382
- * are what the binding establishes for itself as it validates.
1683
+ * What bind() accepts in addition to the data: the three members a binding otherwise copies from the element it
1684
+ * is bound from, and the extended properties. `validators` and `actions` are omitted because a binding uses the
1685
+ * declaration's, and `touched` and `errors` because the binding sets them itself as it validates.
1383
1686
  */
1384
1687
  export declare type IBindParams<T = any, X extends object = Extras> = Partial<Pick<IFieldConstructorParams<T>, 'originalValue' | 'access' | 'visibility'>> & Partial<NoInfer<X>>;
1385
1688
 
@@ -1391,9 +1694,9 @@ export declare interface IFieldConstructorActionsList {
1391
1694
  /**
1392
1695
  * Parameters accepted by field constructors and by bind overrides.
1393
1696
  *
1394
- * Only writable members are listed. valid, validating, busy, fullValue, isChanged, enabled and effectiveEnabled are
1395
- * getter-only, so assigning them throws a TypeError. So are parent and fieldName: a container writes the slots
1396
- * behind them when it takes an element, and nobody else can, which is why the type rejects them.
1697
+ * Only writable members are listed. valid, validating, busy, pending, fullValue, isChanged, enabled and
1698
+ * effectiveEnabled are getter-only, so assigning them throws a TypeError. So are parent and fieldName: only a
1699
+ * container writes the slots behind them, when it takes an element, so the type rejects them.
1397
1700
  */
1398
1701
  export declare type IFieldConstructorParams<T = any> = {
1399
1702
  value: T;
@@ -1405,49 +1708,54 @@ export declare type IFieldConstructorParams<T = any> = {
1405
1708
  } & IFieldConstructorActionsList;
1406
1709
 
1407
1710
  /**
1408
- * What an element's constructor accepts: the parameters the element answers for itself, together with the
1409
- * extended properties its X parameter declares.
1711
+ * What an element's constructor accepts: the element's own parameters and the extended properties its X parameter
1712
+ * declares.
1410
1713
  *
1411
- * X is left out of inference, so an element carries what its X states - `Extras` where no type argument replaces
1412
- * it - and a parameter object naming anything else is rejected as an excess property.
1714
+ * X is excluded from inference, so an element has the properties X declares (`Extras` if no type argument is
1715
+ * given), and a parameter object with any other key is rejected as an excess property.
1413
1716
  *
1414
- * The two halves are made partial separately. `Partial<A & X>` is a mapped type over an intersection, which is
1415
- * what T is inferred through, and inference through it answers with one constituent of a union rather than the
1416
- * union: `new Field({ value: someStringOrNumber })` would be a Field<string>.
1717
+ * The two parts are made partial separately. With `Partial<A & X>`, T would be inferred through a mapped type over
1718
+ * an intersection, which infers one member of a union instead of the union: `new Field({ value:
1719
+ * someStringOrNumber })` would be a Field<string>.
1417
1720
  */
1418
1721
  export declare type IFieldParams<T = any, X extends object = Extras> = Partial<IFieldConstructorParams<T>> & Partial<NoInfer<X>>;
1419
1722
 
1420
1723
  declare class InAllowedValues<T = any> extends Validator {
1421
- constructor(allowedValues: AllowedValues<T>, message?: RenderContentRef);
1724
+ constructor(allowedValues: AllowedValues<T>, options?: ValidationErrorOptions);
1422
1725
  }
1423
1726
 
1424
- /** Answers whether `value` is one of the four accesses. */
1425
- export declare function isAccess(value: unknown): value is Access;
1727
+ /**
1728
+ * Installs `plugin` for every element, including the ones already built: a hook runs on the next write. A plugin
1729
+ * installed twice runs twice. Returns a function that uninstalls it; values stored while it was installed are kept
1730
+ * as they are.
1731
+ */
1732
+ export declare function installPlugin(plugin: Plugin_2): () => void;
1426
1733
 
1427
- export declare function isCallableFunction(msg?: RenderContentRef): msg is RenderContentCallable;
1734
+ /** Returns whether `value` is one of the four accesses. */
1735
+ export declare function isAccess(value: unknown): value is Access;
1428
1736
 
1429
1737
  /**
1430
- * Structural equality that treats a `FieldBase` as what it holds. `isEqual(fieldA, fieldB)` and
1431
- * `isEqual(list.items, other.items)` compare values the way `isEqual(fieldA.value, fieldB.value)` already does,
1432
- * without a call site having to unwrap every element by hand.
1433
- *
1434
- * Two `FieldBase` operands skip `isEqualWith`'s dispatch and compare `.value` directly — about 40% faster than
1435
- * routing the same comparison through the customizer, measured comparing two single-field elements.
1738
+ * Whether `value` is empty: `null`, `undefined`, an empty string, an empty array, an empty `Map` or `Set`, or a
1739
+ * plain object (one without a prototype included) with no own keys. Every built-in validator except `Required` and
1740
+ * `CompareTo` passes an empty value, so a field that may stay empty carries only the other validators, and a field
1741
+ * that may not adds `Required`.
1436
1742
  */
1437
- export declare function isEqual(a: unknown, b: unknown): boolean;
1743
+ declare function isEmptyValue(value: unknown): boolean;
1438
1744
 
1439
1745
  /**
1440
- * Type guard to check if content is a custom component definition
1441
- * @param msg - Content to check
1442
- * @returns True if content is a custom component definition
1746
+ * Structural equality that compares a `FieldBase` by the value it holds. `isEqual(fieldA, fieldB)` and
1747
+ * `isEqual(list.items, other.items)` compare values as `isEqual(fieldA.value, fieldB.value)` does, without
1748
+ * unwrapping each element at the call site.
1749
+ *
1750
+ * Two `FieldBase` operands are compared by `.value` directly, without the `isEqualWith` customizer dispatch.
1443
1751
  */
1444
- export declare function isSimpleComponentDef(msg?: RenderContentRef): msg is SimpleComponentDef;
1752
+ export declare function isEqual(a: unknown, b: unknown): boolean;
1445
1753
 
1446
- /** Answers whether `value` is one of the four visibilities. */
1754
+ /** Returns whether `value` is one of the four visibilities. */
1447
1755
  export declare function isVisibility(value: unknown): value is Visibility;
1448
1756
 
1449
1757
  declare class LengthInRange extends Validator {
1450
- constructor(minLength: number, maxLength: number, message?: RenderContentRef);
1758
+ constructor(minLength: number, maxLength: number, options?: ValidationErrorOptions);
1451
1759
  }
1452
1760
 
1453
1761
  export declare class List<R extends FieldBase = Group, X extends object = Extras> extends Container<ListValue<R>, X> {
@@ -1457,11 +1765,11 @@ export declare class List<R extends FieldBase = Group, X extends object = Extras
1457
1765
  private _itemTemplate?;
1458
1766
  constructor(itemTemplate?: undefined, params?: IFieldParams<ListValueInput<R>, X>);
1459
1767
  constructor(itemTemplate: R, params?: IFieldParams<ListValueInput<R>, X>);
1460
- /** The row array is copied as well: a rollback puts back the set the list held, not the array it went on to hold. */
1768
+ /** The row array is copied as well, so a rollback restores the rows the list held before the transaction. */
1461
1769
  protected [TxCapture](): TxSnapshot;
1462
1770
  /**
1463
- * The copy of a built value that serves as a baseline. The value getter hands out one array per version, and a
1464
- * baseline holding that same array would report every value as its own original.
1771
+ * A copy of a built value, used as a baseline. The value getter returns one array per version, and a baseline
1772
+ * holding that same array would make every value equal to its original.
1465
1773
  */
1466
1774
  private static baseline;
1467
1775
  private processSetValueItem;
@@ -1471,64 +1779,84 @@ export declare class List<R extends FieldBase = Group, X extends object = Extras
1471
1779
  */
1472
1780
  private static elementFor;
1473
1781
  /**
1474
- * Builds the item that fills a gap left by an insert beyond the end of the list: the item template bound to its
1475
- * own values, or, where the list has no template, an empty element of the kind `item` is built into.
1782
+ * Builds an item that fills a gap left by an insert beyond the end of the list: the item template bound to its
1783
+ * own values, or, if the list has no item template, an empty element of the kind `item` is built into.
1476
1784
  */
1477
1785
  private createPaddingItem;
1478
- /** Records that the set of rows changed, so `items` rebuilds the frozen array it hands out at the next read. */
1786
+ /** Records that the set of rows changed, so `items` rebuilds its frozen array at the next read. */
1479
1787
  private rowsChanged;
1480
- /** True where `next` is a different set of rows than `previous`: another count, or another row at a position. */
1788
+ /** True if `next` is a different set of rows than `previous`: a different count, or a different row at a position. */
1481
1789
  private static rowsDiffer;
1790
+ /**
1791
+ * Installs the rows `newValue` describes. With `announce`, a row that leaves the list is announced with a
1792
+ * `ListItemRemovedAction` and a row that enters it with a `ListItemAddedAction`; a row reused at its position is
1793
+ * neither. The construction installs its rows without announcing them.
1794
+ */
1482
1795
  private setValueInternal;
1483
1796
  get value(): ListValue<R>;
1484
1797
  set value(newValue: ListValueInput<R>);
1485
1798
  /**
1486
- * The rows are taken from `source` where the caller supplied no value of its own, so a list nested in a row that
1487
- * a whole-list assignment reuses ends up holding what the template gives it rather than what it held before.
1799
+ * If no value is supplied, the rows are taken from `source`, so a list nested in a row reused by a whole-list
1800
+ * assignment ends up with the item template's rows, not its previous ones.
1488
1801
  */
1489
1802
  protected resetTo(source: FieldBase, value: any): void;
1803
+ protected recordBaseline(): void;
1490
1804
  bind(data?: ListValueInput<R>, overrides?: IBindParams<ListValueInput<R>, X>): List<R, X>;
1805
+ /**
1806
+ * The rows, read so that the caller depends on the set of rows: the read of `rowsVersion` is tracked, and the
1807
+ * array itself is held outside Vue's reactivity. A reactive array would route every element a `splice()` shifts
1808
+ * through the proxy, so inserting or removing a row would cost a proxied write per row after it. Every change
1809
+ * of the set of rows increments `rowsVersion`.
1810
+ */
1811
+ private get rows();
1491
1812
  protected get members(): FieldBase[];
1492
1813
  protected get children(): readonly FieldBase[];
1493
1814
  /**
1494
- * The full value of every row. Where `value` states what the list sends, this states what the list holds: every
1495
- * row whatever its access, and a group row carrying every field of its own. It is what a binding or a reset
1496
- * carries.
1815
+ * The full value of every row. `value` is what the list sends; `fullValue` is what the list holds: every row
1816
+ * whatever its access, and every field of a group row. A binding or a reset copies it.
1497
1817
  */
1498
1818
  get fullValue(): ListFullValue<R>;
1499
1819
  /**
1500
- * How many rows this list holds. The read is tracked, so a template rendering off it re-renders as rows come and
1501
- * go.
1820
+ * The number of rows this list holds. The read is tracked, so a template that reads it re-renders when rows are
1821
+ * added or removed.
1502
1822
  */
1503
1823
  get length(): number;
1504
1824
  /**
1505
- * The rows this list holds, oldest position first. The array is a frozen copy: it states what the list held at
1506
- * the read and nothing writes back through it - `push`, `insert`, `remove` and `clear` are what change the set -
1507
- * so a caller may hold on to it. The rows in it are the live elements, so reading one reports what it holds now.
1825
+ * The rows this list holds, in position order. The array is a frozen copy of the rows at the time of the read and
1826
+ * cannot be written through (`push`, `insert`, `remove` and `clear` change the rows), so a caller may keep it. The
1827
+ * rows in it are the live elements, so a row read from it returns its current state.
1508
1828
  *
1509
- * The copy is built once per change of the set and handed to every reader until the next one: a write inside a
1510
- * row changes what the list serializes without changing which rows it holds, and the array a reader took stays
1511
- * the same one across such a write.
1829
+ * The copy is built once per change of the set of rows and returned to every reader until the next change: a
1830
+ * write inside a row changes what the list sends without changing which rows it holds, and the array stays the
1831
+ * same across such a write.
1512
1832
  */
1513
1833
  get items(): readonly R[];
1514
1834
  get(index: number): R | undefined;
1515
- push(item: any): number;
1835
+ push(item: ListItemInput<R>): number;
1516
1836
  pop(): R | undefined;
1517
1837
  remove(index: number): R | undefined;
1518
- insert(item: any, index: number): number;
1519
- /** Drops every row this list holds out of its tally, so a row that changes its verdict later is not counted. */
1838
+ insert(item: ListItemInput<R>, index: number): number;
1839
+ /** Releases every row from this list, so a later validity change of a row does not affect its invalid count. */
1520
1840
  private releaseRows;
1841
+ /**
1842
+ * Puts the rows in the order `rows` gives, in place: `rows` holds the same rows as the list, in a new order. The
1843
+ * set of rows does not change, so no `ListItemAddedAction` or `ListItemRemovedAction` fires; the value changes and
1844
+ * is announced. The view of a list calls it for `sort()` and `reverse()`; the package does not export the key.
1845
+ */
1846
+ [ReorderRows](rows: readonly R[]): void;
1521
1847
  clear(): void;
1848
+ /** Takes `null` as well as an array of rows: `rebind(null)` empties the list. */
1849
+ rebind(data: ListValueInput<R>): this;
1522
1850
  }
1523
1851
 
1524
- /** the array a list's view is: every read an array has, and the mutations taken as the list's own operations */
1852
+ /** the type of a list's view: every array read, and the mutations performed as the list's own operations */
1525
1853
  declare type ListData<R extends FieldBase> = Omit<Slot<R>[], 'push' | 'unshift' | 'splice' | 'fill' | 'copyWithin'> & {
1526
1854
  push(...items: RowInput<R>[]): number;
1527
1855
  unshift(...items: RowInput<R>[]): number;
1528
1856
  splice(start: number, deleteCount?: number, ...items: RowInput<R>[]): Slot<R>[];
1529
1857
  };
1530
1858
 
1531
- /** what List.fullValue reads back: the full value of every row, whatever its access */
1859
+ /** the value of List.fullValue: the full value of every row, whatever its access */
1532
1860
  export declare type ListFullValue<R extends FieldBase = Group> = R['fullValue'][];
1533
1861
 
1534
1862
  export declare class ListItemAddedAction extends FieldActionBase {
@@ -1537,6 +1865,9 @@ export declare class ListItemAddedAction extends FieldActionBase {
1537
1865
  execute(field: FieldBase, supr: FieldActionExecute, item: any, index: number): void;
1538
1866
  }
1539
1867
 
1868
+ /** What `push()` and `insert()` take: the data a row is built from, or an element. */
1869
+ export declare type ListItemInput<R extends FieldBase> = R['value'] | R;
1870
+
1540
1871
  export declare class ListItemRemovedAction extends FieldActionBase {
1541
1872
  constructor(executorFn: (field: FieldBase, supr: FieldActionExecute, item: any, index: number) => void);
1542
1873
  static get classIdentifier(): symbol;
@@ -1547,18 +1878,18 @@ export declare class ListItemRemovedAction extends FieldActionBase {
1547
1878
  declare interface ListSlots<R extends FieldBase = Group> extends ContainerSlots<ListValue<R>> {
1548
1879
  rows: R[] | null;
1549
1880
  /**
1550
- * Counts the changes to the set of rows. `items` rebuilds the frozen array it hands out when it moves, and
1551
- * only then: a write inside a row changes what the list serializes without changing which rows it holds.
1881
+ * Counts the changes to the set of rows. `items` rebuilds its frozen array only when this changes: a write
1882
+ * inside a row changes what the list sends without changing which rows it holds.
1552
1883
  */
1553
1884
  rowsVersion: number;
1554
- /** the frozen array `items` last handed out, together with the rows version it was built from */
1885
+ /** the frozen array `items` last returned, and the rows version it was built from */
1555
1886
  cachedItems: readonly R[] | null;
1556
1887
  cachedItemsVersion: number;
1557
1888
  }
1558
1889
 
1559
1890
  /**
1560
- * What a List of R reads back: the value of each row it sends, `null` for a row whose access is `'disabled-null'`,
1561
- * and `[]` while it sends none
1891
+ * The value of a List of R: the value of each row it sends, `null` for a row whose access is `'disabled-null'`,
1892
+ * and `[]` if it sends no rows
1562
1893
  */
1563
1894
  export declare type ListValue<R extends FieldBase = Group> = (R['value'] | null)[];
1564
1895
 
@@ -1566,30 +1897,19 @@ export declare type ListValue<R extends FieldBase = Group> = (R['value'] | null)
1566
1897
  export declare type ListValueInput<R extends FieldBase = Group> = ListValue<R> | null;
1567
1898
 
1568
1899
  declare class MaxLength extends Validator {
1569
- constructor(maxLength: number, message?: RenderContentRef);
1900
+ constructor(maxLength: number, options?: ValidationErrorOptions);
1570
1901
  }
1571
1902
 
1572
1903
  declare class MaxValue<T = any> extends Validator {
1573
- constructor(maxValue: T, message?: RenderContentRef);
1904
+ constructor(maxValue: T, options?: ValidationErrorOptions);
1574
1905
  }
1575
1906
 
1576
- /**
1577
- * Marks content for markdown rendering
1578
- */
1579
- export declare class MdString extends String {
1580
- plugins?: any[];
1581
- options?: any;
1582
- constructor(value: string, options?: any, plugins?: any[]);
1583
- }
1584
-
1585
- export declare const MessagesWidget: DefineComponent<Props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
1586
-
1587
1907
  declare class MinLength extends Validator {
1588
- constructor(minLength: number, message?: RenderContentRef);
1908
+ constructor(minLength: number, options?: ValidationErrorOptions);
1589
1909
  }
1590
1910
 
1591
1911
  declare class MinValue<T = any> extends Validator {
1592
- constructor(minValue: T, message?: RenderContentRef);
1912
+ constructor(minValue: T, options?: ValidationErrorOptions);
1593
1913
  }
1594
1914
 
1595
1915
  export declare type NullableAction = Action | null;
@@ -1603,8 +1923,8 @@ export declare type NullableList = List | null;
1603
1923
  export declare type OperandType = any | Statement | FieldBase;
1604
1924
 
1605
1925
  /**
1606
- * Operators provides us a functionality for backend to send us complex condition upon which we send
1607
- * dynamic visibility prop for form input fields
1926
+ * The operators of a `Statement`. A backend can send a condition composed of them, which sets the visibility of
1927
+ * form elements.
1608
1928
  */
1609
1929
  export declare enum Operator {
1610
1930
  NOT = 0,
@@ -1627,107 +1947,165 @@ export declare enum Operator {
1627
1947
 
1628
1948
  export declare namespace Operator {
1629
1949
  export function fromString(operator: string): Operator;
1950
+ /** `mode` as an operator: a number that is an operator value, or a name `fromString()` parses; else throws. */
1630
1951
  export function fromAny(mode: any): Operator;
1952
+ /** Whether `operator` is an operator or the name of one; an unknown name is not, and does not throw. */
1631
1953
  export function isDefined(operator: number | string): boolean;
1954
+ /** Whether `operator` is a logic operator (`NOT` … `NOR`) rather than a comparison. */
1632
1955
  export function isLogicOperator(operator: Operator): boolean;
1633
1956
  }
1634
1957
 
1635
1958
  declare class Pattern extends Validator {
1636
- constructor(pattern: RegExp, message?: RenderContentRef);
1637
- }
1638
-
1639
- declare interface Props {
1640
- message: string | ValidationError[];
1641
- classes?: ClassTypes;
1959
+ constructor(pattern: RegExp, options?: ValidationErrorOptions);
1642
1960
  }
1643
1961
 
1644
1962
  /**
1645
- * A value, renderable three different ways (plain text, markdown, component) - alias for ValidationErrorRenderContent
1963
+ * A plugin. Every hook is optional. The value hooks of the installed plugins run as a pipeline in the order of
1964
+ * installation: the first receives the value being written, each following one receives the previous one's result,
1965
+ * and the last result is stored.
1646
1966
  */
1647
- export declare class RenderableValue extends ValidationErrorRenderContent {
1967
+ declare interface Plugin_2 {
1968
+ /** Called once by `installPlugin()`, with the context the plugin's other hooks use. */
1969
+ setup?(context: PluginContext): void;
1970
+ /**
1971
+ * Called on every write of the value a `Field` holds: construction, the `value` setter and `rebind()`. A rollback
1972
+ * restores the stored value without calling it. `ValueChangedAction` and `field.value` receive the stored value.
1973
+ */
1974
+ onSetValue?(value: unknown, element: FieldBase): unknown;
1975
+ /** Called on every write of `originalValue` of any element, a container's included. */
1976
+ onSetOriginalValue?(value: unknown, element: FieldBase): unknown;
1977
+ /**
1978
+ * Called at the start of every element's construction, before its parameters are applied. `binding` is true for
1979
+ * an element `bind()` builds, a row of a `List` included. The hooks run in the order of installation.
1980
+ */
1981
+ onElementCreated?(element: FieldBase, binding: boolean): void;
1982
+ /**
1983
+ * Called when a container takes `element` as its member, once the transaction that took it commits. Not called
1984
+ * where the transaction is rolled back.
1985
+ */
1986
+ onElementAdopted?(element: FieldBase): void;
1987
+ /** Called after every committed transaction, once its changes are announced. Not called after a rollback. */
1988
+ onCommit?(): void;
1989
+ }
1990
+ export { Plugin_2 as Plugin }
1991
+
1992
+ /** What `installPlugin()` passes to a plugin's `setup()`. */
1993
+ export declare interface PluginContext {
1994
+ /**
1995
+ * Makes a write into the value a field holds a change of the field. It opens a transaction, or joins the open one,
1996
+ * and in it:
1997
+ *
1998
+ * 1. where this is the first such write since the field's last announcement, records `copy()` as the old value;
1999
+ * 2. calls `write()`;
2000
+ * 3. registers `undo()` for a rollback;
2001
+ * 4. runs the field's validators and enrols the field, so the commit fires `ValueChangedAction` with the value
2002
+ * the field holds and the recorded old value.
2003
+ *
2004
+ * `element` is a `Field`; any other element throws a `TypeError`.
2005
+ */
2006
+ changeInPlace(element: FieldBase, write: () => void, undo: () => void, copy: () => unknown): void;
2007
+ /**
2008
+ * True for an element that is part of another element's definition: a binding (an element built by `bind()`,
2009
+ * such as a row of a `List`) or a `List`'s item template.
2010
+ */
2011
+ isInternal(element: FieldBase): boolean;
1648
2012
  }
1649
2013
 
1650
2014
  /**
1651
- * Type for different renderable content formats: plain string, markdown, or custom component
2015
+ * Puts `target` back to its baseline: on `execute()` it calls `target.rebind(target.originalValue)`, which sets the
2016
+ * value to `originalValue`, resets `touched` and revalidates, then calls the next handler in the chain and returns
2017
+ * its result.
2018
+ *
2019
+ * `canExecute()` is true while the target exists, whatever its validity.
1652
2020
  */
1653
- export declare type RenderContent = RenderContentNonCallable | RenderContentCallable;
1654
-
1655
- export declare type RenderContentCallable = () => RenderContentNonCallable;
1656
-
1657
- export declare type RenderContentNonCallable = string | MdString | SimpleComponentDef;
2021
+ export declare class RejectAction extends TargetedExecuteAction {
2022
+ protected readonly target: CommandTarget;
2023
+ constructor(target: CommandTarget);
2024
+ canExecute(action: FieldBase): boolean;
2025
+ }
1658
2026
 
1659
2027
  /**
1660
- * Type for different renderable content formats (supporting references): plain string, markdown, or custom component
2028
+ * Key of the `FieldBase` method that removes, in its subtree, the errors whose rule removes them on `'submit'`.
2029
+ * `SubmitAction` calls it; the package does not export it.
1661
2030
  */
1662
- export declare type RenderContentRef = RenderContent | Ref<RenderContent>;
2031
+ declare const RemoveErrorsOnSubmit: unique symbol;
2032
+
2033
+ /** Key of the `List` method that reorders the rows in place; `view()` calls it, and the package does not export it. */
2034
+ declare const ReorderRows: unique symbol;
1663
2035
 
1664
2036
  declare class Required_2 extends Validator {
1665
2037
  constructor(options?: RequiredOptions);
1666
- constructor(message?: RenderContentRef, options?: RequiredOptions);
1667
2038
  }
1668
2039
 
1669
- /** How the value is read before its length is taken. */
1670
- declare interface RequiredOptions {
2040
+ /** How the value is read before its length is measured, and the error's code and detail. */
2041
+ declare type RequiredOptions = ValidationErrorOptions & {
1671
2042
  /**
1672
- * Whether a string is trimmed before it is measured, so that whitespace alone is no value. Defaults to true.
1673
- * Set it to false where the spaces are part of what the field holds.
2043
+ * Whether a string is trimmed before it is measured, so that whitespace alone counts as no value. Defaults to
2044
+ * true. Set it to false if spaces are part of the field's value.
1674
2045
  */
1675
2046
  trim?: boolean;
1676
- }
2047
+ };
1677
2048
 
1678
- /** what a list's view takes as a row: the data a row is built from, an element, or the view of one */
2049
+ /** what a list's view accepts as a row: the data a row is built from, an element, or the view of one */
1679
2050
  declare type RowInput<R extends FieldBase> = R['value'] | R | View<R>;
1680
2051
 
1681
- /** asked by a validator before it runs: whether the element is sent nowhere, read without tracking */
2052
+ /** read by a validator before it runs: whether the element is not sent at all, read without tracking */
1682
2053
  declare const SentNowhere: unique symbol;
1683
2054
 
1684
- /** Writes the members `newConfig` names and leaves the rest as they stand. */
1685
- export declare function setConfig(newConfig: Partial<FormsConfig>): void;
1686
-
1687
2055
  /**
1688
- * Interface for custom component content definition
2056
+ * Sets the rules of the origins in `policies` for every element without an `ErrorPolicy` that names them. An origin
2057
+ * not in `policies` keeps its rule. The built-in rules are `{ validEffect: true, removeOn: 'edit' }` for `'server'`
2058
+ * and `{ validEffect: true, removeOn: 'never' }` for every other origin.
2059
+ *
2060
+ * Returns a function that restores the rules in force before the call. `valid` reflects a change at once; the
2061
+ * validity an element announces through `ValidChangedAction` is recomputed at its next validity change, so the
2062
+ * defaults are set before forms are built. Throws a TypeError for a rule `ErrorPolicy` refuses.
1689
2063
  */
1690
- export declare interface SimpleComponentDef {
1691
- componentName: string;
1692
- componentProps?: Record<any, any>;
1693
- componentVHtml?: string;
1694
- }
2064
+ export declare function setDefaultErrorPolicies(policies: ErrorPolicies): () => void;
1695
2065
 
1696
- /** a member of the form in the shape a view hands it out: the view of a container, the value of anything else */
2066
+ /** the type a view returns for a member: the view of a container, the value of any other element */
1697
2067
  declare type Slot<E> = E extends Container ? View<E> : E extends FieldBase ? E['value'] : never;
1698
2068
 
2069
+ /** What an application states about an element for the devtools. */
2070
+ export declare interface StateDescription {
2071
+ /** The name the devtools show; defaults to the element's class and a number. */
2072
+ name?: string;
2073
+ /** The file the element is defined in; defaults to the file of the code that constructed it. */
2074
+ file?: string;
2075
+ }
2076
+
1699
2077
  export declare class Statement {
1700
2078
  private readonly operand1;
1701
2079
  private readonly operator;
1702
2080
  private readonly operand2;
1703
2081
  /**
1704
2082
  * An operand is a nested `Statement`, a `FieldBase` whose value is compared, or a literal. `undefined` and a
1705
- * function are neither: they are what a misspelled field name and a field accessor handed over uncalled answer
1706
- * with, and a statement built from one compares nothing and never fires. The position names which of the two
1707
- * operands is at fault, so the error points at the place the name was written.
2083
+ * function are not operands: they result from a misspelled field name and from an accessor passed without being
2084
+ * called, and a statement built from one would compare nothing and never fire. The error message includes the
2085
+ * operand's position.
1708
2086
  */
1709
2087
  private static validateOperand;
1710
2088
  /**
1711
- * `NOT` reads one operand, so it is stated with one. Every other operator compares two and takes both, and so
1712
- * does an operator held in a variable - `Operator.fromString()` answers with the type rather than with the
1713
- * constant, and the compiler cannot tell from it which of the two forms is meant.
2089
+ * `NOT` reads one operand, so it takes one. Every other operator compares two and takes both, as does an operator
2090
+ * held in a variable: `Operator.fromString()` returns the type, not the constant, so the compiler cannot
2091
+ * determine which of the two forms applies.
1714
2092
  *
1715
- * @throws TypeError where an operand the statement reads is undefined or a function.
2093
+ * @throws TypeError if an operand the statement reads is undefined or a function.
1716
2094
  */
1717
2095
  constructor(operand1: OperandType, operator: Operator.NOT);
1718
2096
  constructor(operand1: OperandType, operator: Operator, operand2: OperandType);
1719
2097
  /**
1720
- * The value an operand contributes. A field operand names a field of the record the statement is evaluated in:
1721
- * the same statement over a `List` reads row 3's field while row 3 is the record, and a field belonging to no
1722
- * record of the statement's own - a form field above the list - is read where it stands. A record that does not
1723
- * hold the field yet contributes undefined, which is what a half-built row answers with.
2098
+ * Returns the value of an operand. A field operand refers to the corresponding element of the record the
2099
+ * statement is evaluated in: the same statement over a `List` reads row 3's element when row 3 is the record, and
2100
+ * an element outside the statement's records (a form field above the list) is read directly. If the record does
2101
+ * not hold the element yet (a partially built row), the value is undefined.
1724
2102
  */
1725
2103
  private static valueOf;
1726
2104
  get operand1Value(): any;
1727
2105
  get operand2Value(): any;
1728
2106
  /**
1729
- * The result of the statement, over the record `scope` belongs to where one is given and over the fields the
1730
- * statement was built from where it is not.
2107
+ * The result of the statement, over the record `scope` belongs to if given, and over the elements the statement
2108
+ * was built from otherwise.
1731
2109
  */
1732
2110
  evaluate(scope?: FieldBase): boolean;
1733
2111
  /**
@@ -1737,151 +2115,215 @@ export declare class Statement {
1737
2115
  collectFields(): Set<FieldBase>;
1738
2116
  }
1739
2117
 
1740
- export declare const strings: {
1741
- Required: string;
1742
- MinValue: string;
1743
- MaxValue: string;
1744
- ValueInRange: string;
1745
- MinLength: string;
1746
- MaxLength: string;
1747
- LengthInRange: string;
1748
- Pattern: string;
1749
- InAllowedValues: string;
1750
- ValidationFailed: string;
1751
- };
2118
+ /**
2119
+ * Sends the value of `target` to `handler`. On `execute()` it:
2120
+ *
2121
+ * 1. waits until `target.validating` is false, so a validation started in the same event is finished. It does not
2122
+ * await `target.settled()`: the action is `busy` while it runs, so the target is `pending` until it returns;
2123
+ * 2. where `target.valid` is false, ends with a `SubmitRefusedException` with `reason` `'invalid'`, which
2124
+ * `execute()` resolves with;
2125
+ * 3. removes, from the target and every element below it, the errors whose rule removes them on `'submit'` (see
2126
+ * `ErrorPolicy`);
2127
+ * 4. where the target's `access` is `'editable'` and `lock` is not false, sets it to `'readonly'`;
2128
+ * 5. calls `handler(target.value, target)` and awaits it;
2129
+ * 6. where the result is not `undefined` and `rebind` is not false, calls `target.rebind(result)`;
2130
+ * 7. sets the target's `access` back to `'editable'` where step 4 set it and it is still `'readonly'`, whether the
2131
+ * handler succeeded or failed;
2132
+ * 8. calls the next handler in the chain and returns a `SubmitResult`: the action, the value sent and the value
2133
+ * `handler` returned.
2134
+ *
2135
+ * A second `execute()` while a submit of the same action is running is refused with a `SubmitRefusedException`
2136
+ * with `reason` `'running'`.
2137
+ *
2138
+ * A `handler` that throws or rejects ends the submit with a `SubmitFailedException` whose `cause` is the error;
2139
+ * `execute()` resolves with it and the target is not changed. Mapping a server's field errors to the fields is the
2140
+ * handler's: it writes them to `field.errors` before it throws.
2141
+ *
2142
+ * The resolved value is `SubmitResult<R> | CommandException`. `execute()` is typed `Promise<any>`, because the
2143
+ * chain may hold other handlers; the caller states the type where it awaits the result.
2144
+ *
2145
+ * `'readonly'` sends and validates the target as `'editable'` does, so its `value`, `valid` and `isChanged` do not
2146
+ * change and no validator runs because of the lock; the members inherit it through `effectiveAccess`, so every
2147
+ * input below the target is not enabled while the handler runs. The rebind in step 6 replaces the target's value
2148
+ * with the result, so a change written to the target by code while the handler runs is lost and `isChanged` is
2149
+ * false afterwards. `busy` and `pending` report the running submit.
2150
+ *
2151
+ * `canExecute()` is true while the target is valid and not `pending`, so `Action.executable` disables a submit
2152
+ * button while the form is invalid or a validation is running.
2153
+ */
2154
+ export declare class SubmitAction<R = any> extends TargetedExecuteAction {
2155
+ protected readonly target: CommandTarget;
2156
+ constructor(target: CommandTarget, handler: (value: any, target: FieldBase) => R | Promise<R>, options?: SubmitOptions);
2157
+ canExecute(action: FieldBase): boolean;
2158
+ }
2159
+
2160
+ /** The `CommandException` a `SubmitAction` ends with when its handler throws or rejects; `cause` is what it threw. */
2161
+ export declare class SubmitFailedException extends CommandException {
2162
+ constructor(cause: unknown);
2163
+ }
2164
+
2165
+ /** How a `SubmitAction` treats its target. */
2166
+ export declare interface SubmitOptions {
2167
+ /**
2168
+ * Whether a result other than `undefined` is written back with `target.rebind(result)`, which makes it the new
2169
+ * baseline: `isChanged` is false, `touched` is false and the errors are revalidated. Defaults to true.
2170
+ */
2171
+ rebind?: boolean;
2172
+ /**
2173
+ * Whether an `'editable'` target is `'readonly'` while the handler runs, so no input reaches it during the
2174
+ * submit. Defaults to true.
2175
+ */
2176
+ lock?: boolean;
2177
+ }
2178
+
2179
+ /** Why a `SubmitAction` refused to submit: the target is invalid, or a submit of the same action is running. */
2180
+ export declare type SubmitRefusalReason = 'invalid' | 'running';
2181
+
2182
+ /**
2183
+ * The `CommandException` a `SubmitAction` ends with when it refuses to submit and does not call the handler;
2184
+ * `reason` states why.
2185
+ */
2186
+ export declare class SubmitRefusedException extends CommandException {
2187
+ readonly reason: SubmitRefusalReason;
2188
+ constructor(reason: SubmitRefusalReason);
2189
+ }
2190
+
2191
+ /** What `execute()` of an action with a `SubmitAction` resolves with after a successful submit. */
2192
+ export declare interface SubmitResult<R = any> {
2193
+ /** The action that ran the submit. */
2194
+ action: FieldBase;
2195
+ /** The value passed to the handler: the target's `value`. */
2196
+ sent: unknown;
2197
+ /** The value the handler returned. */
2198
+ received: R;
2199
+ }
2200
+
2201
+ /** An `ExecuteAction` that works on a target element; `Container.confirm()` and `reject()` find it by its target. */
2202
+ export declare abstract class TargetedExecuteAction extends ExecuteAction {
2203
+ protected abstract readonly target: CommandTarget;
2204
+ /** The element this handler works on when it runs on `action`, or undefined where the callback returns none. */
2205
+ targetFor(action: FieldBase): FieldBase | undefined;
2206
+ }
1752
2207
 
1753
2208
  declare class Transaction {
1754
2209
  private readonly participants;
1755
- /** what a rollback has to put back beyond the state slots, newest last */
2210
+ /** what a rollback restores beyond the state slots, newest last */
1756
2211
  private readonly undo;
1757
- /** what the commit has to do once the change stands, in the order it was handed in */
2212
+ /** work the commit runs after the change is complete, in registration order */
1758
2213
  private readonly settled;
1759
- /** true once the transaction has been unwound, which is what tells a run started inside it to say nothing */
2214
+ /** true once the transaction has been rolled back; a run started inside it then announces nothing */
1760
2215
  private unwound;
1761
- /** the depth the announcement in progress is working at, -1 while none is */
2216
+ /** the depth the current announcement pass is processing, -1 while no pass runs */
1762
2217
  private passDepth;
1763
- /** set while a pass is running and an element it has already passed the depth of gets enrolled */
2218
+ /** set when, during a pass, an element is enrolled at or below the depth being processed */
1764
2219
  private restartPass;
1765
- /** true for a transaction that was rolled back rather than committed */
2220
+ /** true for a transaction that was rolled back */
1766
2221
  get rolledBack(): boolean;
1767
2222
  private participant;
1768
2223
  /**
1769
- * Records the state of an element the first time the transaction modifies it. The whole of the mutable state
1770
- * goes into the snapshot rather than the part being written: a rollback that restored some of it would leave
1771
- * the element in a state the form never held.
2224
+ * Records the state of an element the first time the transaction modifies it. The snapshot contains all of the
2225
+ * mutable state, not only the part being written: a partial restore would leave the element in a state the form
2226
+ * never had.
1772
2227
  */
1773
2228
  touch(element: FieldBase): void;
1774
- /** Enrols an element as one whose value the commit has to announce. `force` skips the comparison. */
2229
+ /** Enrols an element whose value the commit announces. `force` skips the comparison. */
1775
2230
  markValueChanged(element: FieldBase, force: boolean): void;
1776
- /** Enrols an element as one whose verdict the commit has to re-form. */
2231
+ /** Enrols an element whose access or visibility changed; the commit announces the net change. */
2232
+ markFlagsDirty(element: FieldBase): void;
2233
+ /** Enrols an element whose validity the commit recomputes. */
1777
2234
  markValidityDirty(element: FieldBase): void;
1778
2235
  /**
1779
- * Queues an event that states an operation rather than a state. Added and removed items have no net over a
1780
- * transaction, so they are neither compared nor coalesced: the commit emits them in the order they happened.
2236
+ * Queues an event that describes an operation, not a state. Added and removed items have no net result over a
2237
+ * transaction, so they are neither compared nor merged: the commit emits them in the order they happened.
1781
2238
  */
1782
2239
  recordStructural(element: FieldBase, event: TxStructuralEvent): void;
1783
- /** True where the commit still owes this element a value announcement. */
2240
+ /** True if the commit has a pending value announcement for this element. */
1784
2241
  willAnnounceValue(element: FieldBase): boolean;
1785
2242
  /**
1786
- * Registers what a rollback has to put back beyond the element's state slots. The snapshot covers the slots,
1787
- * which is everything an ordinary write touches; an operation that replaces something else the element carries
1788
- * hands its own undo in here rather than making every snapshot carry the thing.
2243
+ * Registers an undo step for state outside the element's state slots. The snapshot covers the slots, which is
2244
+ * everything a regular write modifies; an operation that replaces anything else registers its own undo here, so
2245
+ * the snapshot does not have to include it.
1789
2246
  */
1790
2247
  whenRolledBack(work: () => void): void;
1791
2248
  /**
1792
- * Registers work that runs once the transaction has committed, and not at all where it is rolled back. It is
1793
- * how an operation defers a step that cannot be taken back - cancelling work in flight, for one - until the
1794
- * change it belongs to actually stands.
2249
+ * Registers work that runs after the transaction commits, and not at all if it is rolled back. An operation uses
2250
+ * it to defer a step that cannot be undone (for example, cancelling work in flight) until its change is
2251
+ * committed.
1795
2252
  */
1796
2253
  whenCommitted(work: () => void): void;
1797
2254
  /**
1798
- * Notes that an element at or below the depth the pass in progress is working at has been enrolled. The pass
1799
- * then gives up the rest of its batch and is started again over what is now owed, so the newcomer is reached
1800
- * before the containers above it: an element a handler writes must still be announced before the container
1801
- * whose composed value carries that write. The depth is only measured while a pass is running - outside one
1802
- * there is nothing the answer would change.
2255
+ * Records that an element at or below the depth of the running pass has been enrolled. The pass then stops and
2256
+ * restarts over the pending entries, so the new element is processed before the containers above it: an element
2257
+ * a handler writes is announced before the container whose composed value includes that write. The depth is
2258
+ * computed only while a pass runs; outside a pass it has no effect.
1803
2259
  */
1804
2260
  private noteDepth;
1805
2261
  /**
1806
- * Puts every element the transaction modified back as it found it. Nothing is announced: from an observer's
1807
- * point of view the transaction never happened. What a rollback cannot take back are side effects - a handler
1808
- * that called a server during the transaction already did.
2262
+ * Restores every element the transaction modified to its state before the transaction. Nothing is announced, so
2263
+ * an observer sees no change. A rollback does not undo side effects, such as a server call a handler made during
2264
+ * the transaction.
1809
2265
  */
1810
2266
  rollback(): void;
1811
2267
  /**
1812
- * Announces what the transaction did. Values first and verdicts after, because a container's validators run
1813
- * with its value announcement and the verdict they reach is what the validity pass then reports. Both passes
1814
- * run deepest first - field, then row, then list - which is the order the change travelled in.
2268
+ * Announces the transaction's changes: access, enabled and visibility first, then values, then validity, because
2269
+ * a container's validators run with its value announcement and the validity pass reports their result. Every pass
2270
+ * runs deepest first (field, then row, then list), the order in which the change propagates.
1815
2271
  *
1816
- * A handler may write while the commit runs; its writes join this transaction, so both passes repeat until
1817
- * nothing is left dirty.
2272
+ * A handler may write while the commit runs; its writes join this transaction, so the passes repeat until nothing
2273
+ * is dirty.
1818
2274
  */
1819
2275
  commit(): void;
1820
2276
  /**
1821
- * The dirty participants a pass has to visit, one bucket per nesting depth; ties keep the order they were
1822
- * enrolled in. A nesting depth is a small integer, so the elements go into buckets rather than through a
1823
- * comparison sort: a whole-list assignment enrols one participant per field, and ordering those by comparison
1824
- * would cost more than the announcement it orders.
2277
+ * The dirty participants a pass visits, one bucket per nesting depth; within a depth they keep enrolment order.
2278
+ * A nesting depth is a small integer, so bucketing replaces a comparison sort: a whole-list assignment enrols one
2279
+ * participant per field, and a comparison sort of those would cost more than the announcement itself.
1825
2280
  */
1826
2281
  private buckets;
1827
2282
  /**
1828
- * Runs one pass over the dirty participants, deepest bucket first; the caller repeats it until it answers
1829
- * false. The buckets are taken once, and the pass gives up as soon as a handler enrols an element at or below
1830
- * the depth being drained: that element is not in the bucket being walked, and going on would reach the
1831
- * containers above it first. The caller's next pass takes fresh buckets and finds it at its own depth.
2283
+ * Runs one pass over the dirty participants, deepest bucket first; the caller repeats it until it returns false.
2284
+ * The buckets are built once, and the pass stops as soon as a handler enrols an element at or below the depth
2285
+ * being processed: that element is not in the current bucket, and continuing would process the containers above
2286
+ * it first. The caller's next pass builds new buckets that include it at its depth.
1832
2287
  */
1833
2288
  private pass;
1834
2289
  private announceValues;
2290
+ private announceFlags;
1835
2291
  private settleValidity;
1836
2292
  }
1837
2293
 
1838
2294
  /**
1839
- * Runs `fn` as one atomic change. The writes it makes land in the elements as they are made and the events they
1840
- * produce are announced once, at the end, over the net result.
2295
+ * Runs `fn` as one atomic change. Its writes are applied to the elements immediately, and the resulting events are
2296
+ * announced once, at the end, for the net result.
1841
2297
  *
1842
- * A call made while a transaction is already open joins it: nothing is committed until the outermost call
1843
- * returns. A throw out of `fn` rolls the whole transaction back and rethrows, and `tx.rollback()` rolls it back
1844
- * without an error, in which case the call answers undefined.
2298
+ * A call made while a transaction is open joins it: nothing is committed until the outermost call returns. An
2299
+ * exception thrown from `fn` rolls back the whole transaction and is rethrown; `tx.rollback()` rolls it back
2300
+ * without an error, and the call returns undefined.
1845
2301
  *
1846
2302
  * The handle `fn` receives is usable only for the duration of that call; calling it afterwards throws a TypeError.
1847
2303
  *
1848
- * @throws TypeError immediately if `fn` returns a thenable - a transaction cannot cross an await.
2304
+ * @throws TypeError immediately if `fn` returns a thenable: a transaction cannot span an await.
1849
2305
  */
1850
2306
  export declare function transaction<R>(fn: (tx: TransactionControl) => R): R | undefined;
1851
2307
 
1852
2308
  export declare interface TransactionControl {
1853
2309
  /**
1854
- * Undoes everything the transaction has done and ends it, announcing nothing. It unwinds from the point of
1855
- * the call, so nothing after it runs. There are no savepoints: a nested call rolls back the whole transaction
1856
- * it joined, not its own part of it.
2310
+ * Undoes everything the transaction has done and ends it, announcing nothing. It unwinds from the point of the
2311
+ * call, so no code after it runs. There are no savepoints: a nested call rolls back the whole transaction it
2312
+ * joined, not only its own part.
1857
2313
  *
1858
- * @throws TypeError where the transaction the handle belongs to has already closed.
2314
+ * @throws TypeError if the transaction the handle belongs to has already closed.
1859
2315
  */
1860
2316
  rollback(): never;
1861
2317
  }
1862
2318
 
1863
- /** A built-in validator's default message, translated and reactive to a later `translateStrings` call. */
1864
- export declare function translatedMessage(key: keyof typeof strings): ComputedRef<string | MdString>;
1865
-
1866
- export declare const translateStrings: (cb: TranslateStringsCallback< {
1867
- Required: string;
1868
- MinValue: string;
1869
- MaxValue: string;
1870
- ValueInRange: string;
1871
- MinLength: string;
1872
- MaxLength: string;
1873
- LengthInRange: string;
1874
- Pattern: string;
1875
- InAllowedValues: string;
1876
- ValidationFailed: string;
1877
- }>) => void;
2319
+ declare const TxAnnounceFlags: unique symbol;
1878
2320
 
1879
2321
  declare const TxAnnounceValue: unique symbol;
1880
2322
 
1881
2323
  /**
1882
- * The protocol a transaction drives its participants through. The four members are symbol-keyed so that they
1883
- * carry no name a consumer could reach or collide with, and they live on the prototype, so no walker over an
1884
- * element's own keys sees them either.
2324
+ * The protocol a transaction uses to call its participants. The members are symbol-keyed, so a consumer cannot
2325
+ * reach them by name or collide with them, and they are on the prototype, so a walk over an element's own keys
2326
+ * does not find them.
1885
2327
  */
1886
2328
  declare const TxCapture: unique symbol;
1887
2329
 
@@ -1890,20 +2332,19 @@ declare const TxRestore: unique symbol;
1890
2332
  declare const TxSettleValidity: unique symbol;
1891
2333
 
1892
2334
  /**
1893
- * A transaction is the unit an observer sees a change in. Every mutating operation runs inside one: where the
1894
- * caller opens none, the operation is the transaction, so a single write is atomic without anything having to be
1895
- * remembered at the call site.
2335
+ * A transaction is the unit in which an observer sees a change. Every mutating operation runs inside one: if the
2336
+ * caller has not opened one, the operation is its own transaction, so a single write is atomic without any action
2337
+ * at the call site.
1896
2338
  *
1897
- * Writes land in the element straight away and only the announcement waits. At commit the net transitions are
1898
- * measured against the state the elements last announced and each is announced once, so a value that goes A -> B
1899
- * -> A within one transaction says nothing. Validators run while the transaction is open, because the verdict
1900
- * they reach is what the commit announces; every other action fires at commit.
2339
+ * Writes are applied to the element immediately; only the announcement is deferred. At commit the net changes are
2340
+ * compared against the state the elements last announced and each is announced once, so a value that goes
2341
+ * A -> B -> A within one transaction is not announced. Validators run while the transaction is open, because the
2342
+ * commit announces their result; every other action fires at commit.
1901
2343
  *
1902
- * A transaction may not cross an await: transaction() throws when the callback returns a thenable. Two
1903
- * overlapping transactions therefore cannot exist, and an asynchronous validator settling later opens one of its
1904
- * own at that moment.
2344
+ * A transaction cannot span an await: transaction() throws when the callback returns a thenable. Two overlapping
2345
+ * transactions therefore cannot exist, and an asynchronous validator that settles later opens its own transaction.
1905
2346
  */
1906
- /** the slots of one element as they stood when the transaction first modified it */
2347
+ /** the slots of one element as they were when the transaction first modified it */
1907
2348
  declare type TxSnapshot = Record<string, any>;
1908
2349
 
1909
2350
  /** a ListItemAddedAction or ListItemRemovedAction waiting for the commit that will emit it */
@@ -1915,76 +2356,59 @@ declare interface TxStructuralEvent {
1915
2356
  index: number;
1916
2357
  }
1917
2358
 
2359
+ /** Key of the `FieldBase` getter for the generation counter of its validators; the package does not export it. */
2360
+ declare const ValidationEpoch: unique symbol;
2361
+
1918
2362
  /**
1919
- * Base validation error class with component rendering capabilities
2363
+ * An error on an element. It is data: the library does not render it. A renderer chooses the text for `code` and
2364
+ * `params` and falls back to `detail`.
1920
2365
  */
1921
- export declare class ValidationError {
1922
- code?: string | undefined;
2366
+ export declare class ValidationError implements ErrorDescription {
2367
+ readonly code: string;
2368
+ readonly params: Readonly<Record<string, unknown>>;
2369
+ readonly detail: string;
1923
2370
  private readonly statedOrigin?;
1924
2371
  /**
1925
- * @param code Machine-readable identifier of what failed, in kebab-case. Every validator this library ships states
1926
- * one, so code that reacts to a particular failure does not have to match the message text, which is translated
1927
- * and configurable. It is optional: an error built by hand carries whatever its author gives it, or nothing.
1928
- * @param statedOrigin Where the error comes from, where its author states it; see `origin`.
2372
+ * @param code Machine-readable identifier of what failed, in snake_case.
2373
+ * @param params The values of the failure, such as `minValue` for `min_value`.
2374
+ * @param detail The failure in English, plain text. Stored as given.
2375
+ * @param statedOrigin The origin of the error, if its author sets it; see `origin`.
1929
2376
  */
1930
- constructor(code?: string | undefined, statedOrigin?: ErrorOrigin | undefined);
2377
+ constructor(code: string, params: Readonly<Record<string, unknown>>, detail: string, statedOrigin?: ErrorOrigin | undefined);
1931
2378
  /**
1932
- * Where the error comes from: the origin its author stated, and otherwise `'validator'` for an error a validator
1933
- * produced - a validator stamps every error it hands a field - and `'application'` for one written into `errors`
1934
- * by any other code. It is what a rendering layer reads to decide when to show the error, and what code reads to
1935
- * withdraw the errors of one origin and leave the rest.
2379
+ * The origin its author set. Otherwise `'validator'` for an error a validator produced (a validator stamps every
2380
+ * error it puts on a field) and `'application'` for one written into `errors` by any other code.
1936
2381
  */
1937
2382
  get origin(): ErrorOrigin;
1938
2383
  /**
1939
- * True where `other` is an error of this class that renders exactly as this one does and reports the same code.
1940
- * Two runs of one validator over an unchanged value produce two instances of one message, and this is what lets
1941
- * the validator hand the field back the instance it already holds rather than a fresh one: an equal error is not
1942
- * a new error, and nothing re-renders over a verdict that did not move.
1943
- *
1944
- * The comparison is over what renders - the component, its bindings, its body and the classes - because that is
1945
- * what a reader of `field.errors` sees. A structural comparison of the errors themselves answers nothing useful:
1946
- * `ValidationErrorRenderContent` holds a Vue `computed`, and two of those are never structurally equal.
2384
+ * True if `other` has the same class, code, params, detail and stated origin. If a new run produces an error for
2385
+ * which this is true, the validator keeps the instance the field already holds, so an unchanged error is not
2386
+ * replaced in `field.errors`.
1947
2387
  */
1948
2388
  sameAs(other: ValidationError): boolean;
1949
- get componentName(): string;
1950
- get componentBindings(): {};
1951
- get componentBody(): string;
1952
- get extraClasses(): ClassTypes;
1953
2389
  }
1954
2390
 
1955
2391
  /**
1956
- * Validation error that supports multiple content types (plain text, markdown, component)
2392
+ * The `code` and `detail` a built-in validator uses on its error in place of its own. A `detail` requires a `code`:
2393
+ * a renderer chooses the text by the code, so a detail under the validator's own code is not shown where the
2394
+ * renderer has a text for that code.
1957
2395
  */
1958
- export declare class ValidationErrorRenderContent extends ValidationError {
1959
- classes: ClassTypes;
1960
- private text;
1961
- private textType;
1962
- constructor(text: RenderContentRef, classes?: ClassTypes, code?: string, origin?: ErrorOrigin);
1963
- get resolvedText(): RenderContentNonCallable;
1964
- get getTextType(): "string" | "md" | "component";
1965
- get componentName(): string;
1966
- get componentBindings(): Record<any, any>;
1967
- get componentBody(): string;
1968
- get extraClasses(): ClassTypes;
1969
- }
1970
-
1971
- /**
1972
- * Simple text-only ValidationError
1973
- */
1974
- export declare class ValidationErrorText extends ValidationError {
1975
- text: string;
1976
- classes: ClassTypes;
1977
- constructor(text: string, classes?: ClassTypes, code?: string, origin?: ErrorOrigin);
1978
- get componentName(): string;
1979
- get componentBody(): string;
1980
- get extraClasses(): ClassTypes;
1981
- }
2396
+ declare type ValidationErrorOptions = {
2397
+ /** The error's `code`. Defaults to the validator's own, such as `required`. */
2398
+ code?: string;
2399
+ detail?: never;
2400
+ } | {
2401
+ /** The error's `code`. */
2402
+ code: string;
2403
+ /** The error's English `detail`, plain text. `{name}` placeholders are replaced with the error's `params`. */
2404
+ detail?: string;
2405
+ };
1982
2406
 
1983
2407
  /**
1984
- * What a validator does with a value. `signal` aborts when the verdict this call would reach stops counting - a
1985
- * newer run over the same field, a field the validator was taken off once that removal stands, a transaction that
1986
- * was unwound - so an asynchronous check hands it to the work it commissions and stops paying for an answer nobody
1987
- * will read. A function that has nothing to cancel ignores it.
2408
+ * The validation of a value. `signal` aborts when the result of this call will no longer be applied: a newer run
2409
+ * over the same field, the validator's removal from the field once that removal is committed, a rolled-back
2410
+ * transaction. An asynchronous check passes it to the work it starts, so that work is cancelled. A function with
2411
+ * nothing to cancel ignores it.
1988
2412
  */
1989
2413
  declare type ValidationFunction<T = any> = (newValue: T, oldValue: T, field: FieldBase<T>, signal: AbortSignal) => ValidationFunctionResult | Promise<ValidationFunctionResult>;
1990
2414
 
@@ -2002,52 +2426,52 @@ declare class Validator<T = any> extends ValueChangedAction {
2002
2426
  */
2003
2427
  constructor(validationFn: ValidationFunction<T>);
2004
2428
  /**
2005
- * Returns the error instance this validator owns and may later withdraw: the argument itself when it carries no
2006
- * ownership stamp or already carries this validator's, a copy of it when it belongs to another validator. The
2007
- * stamp is not configurable, so an instance one validator owns can never be reassigned to another; the copy is
2008
- * what makes an error instance shareable between validators, and it keeps the prototype and every own property,
2009
- * including the non-enumerable ones, so it renders exactly like the instance it was made from.
2429
+ * Returns the error instance this validator owns and may later remove: the argument itself if it has no
2430
+ * ownership stamp or already has this validator's, and a copy if it belongs to another validator. The stamp is
2431
+ * not configurable, so an instance owned by one validator cannot be reassigned to another; the copy allows one
2432
+ * error instance to be shared between validators, and keeps the prototype and every own property, including the
2433
+ * non-enumerable ones, so it renders like the original.
2010
2434
  */
2011
2435
  private claim;
2012
2436
  static get classIdentifier(): symbol;
2013
2437
  get eager(): boolean;
2014
2438
  /**
2015
- * Takes this validator off `field`: the errors it put there are withdrawn and the verdict is re-formed over what
2016
- * the validators the field still holds have to say. Withdrawing them is what keeps a field from staying invalid
2017
- * on an error no validator is left to take back.
2439
+ * Removes this validator from `field`: the errors it put there are removed and validity is recomputed over the
2440
+ * remaining validators. Otherwise the field would stay invalid on an error no validator removes.
2018
2441
  *
2019
- * A run in flight over the field is cancelled once the removal stands, and not before: a transaction that
2020
- * unwinds puts the validator and its epoch back, and the run it never cancelled goes on to reach the verdict the
2021
- * field is then owed. Cancelling it as the removal is made would leave the field reporting itself valid over a
2022
- * value nothing checked, on the strength of a transaction that never happened.
2442
+ * A run in flight over the field is cancelled when the removal is committed, not earlier: a rollback restores the
2443
+ * validator and its epoch, and the run, still active, then applies its result. Cancelling at the removal would
2444
+ * leave the field valid over an unchecked value after a rollback.
2023
2445
  */
2024
2446
  unregisterFrom(field: FieldBase): void;
2025
2447
  /**
2026
- * Cancels the asynchronous run in flight over `field`, where there is one. It is called once the field has
2027
- * stopped holding this validator: the field's validation epoch has moved on by then, so the run's verdict is
2028
- * already dropped and the signal it handed its check aborts with it.
2448
+ * Cancels the asynchronous run in flight over `field`, if any. It is called after the validator is removed from
2449
+ * the field: the field's validation epoch has changed, so the run's result is discarded and its signal aborts.
2029
2450
  */
2030
2451
  protected abandonRun(field: FieldBase): void;
2031
2452
  /**
2032
- * What this validator remembers about one of the fields it validates. One instance may be registered on several
2033
- * fields - every row of a list carries the instances the item template carries - so each field has a record of
2034
- * its own. A subclass that remembers more widens the record by overriding `newBindingState`.
2453
+ * The validator's state for one of the fields it validates. One instance may be registered on several fields
2454
+ * (every row of a list has the same instances as the item template), so each field has its own state. A subclass
2455
+ * extends it by overriding `newBindingState`.
2035
2456
  */
2036
2457
  protected bindingState(field: FieldBase<any>): ValidatorBindingState;
2037
2458
  /**
2038
- * The record a field starts with. `run` is the sequence number of the newest run over that field: every
2039
- * execution takes the next one and a result is applied only while its number is still the newest, so a slow run
2040
- * cannot overwrite the verdict of a faster one that started after it.
2459
+ * The initial state for a field. `run` is the sequence number of the newest run over that field: every execution
2460
+ * takes the next number and a result is applied only while its number is the newest, so a slow run cannot
2461
+ * overwrite the result of a faster one that started after it.
2041
2462
  */
2042
2463
  protected newBindingState(): ValidatorBindingState;
2043
- protected replacePlaceholdersFunction(text: RenderContentRef, replace: Record<string, any>): RenderContentRef;
2044
- protected replacePlaceholders(text: RenderContentRef, replace: Record<string, any>): RenderContentRef;
2464
+ /**
2465
+ * Returns the error a built-in validator reports: `code` and `detail` from `options` if set, the validator's own
2466
+ * otherwise, with `params` substituted into the detail.
2467
+ */
2468
+ protected errorFor(options: ValidationErrorOptions | undefined, code: string, detail: string, params: Record<string, unknown>): ValidationError;
2045
2469
  }
2046
2470
 
2047
- /** What a validator remembers about one field it is registered on; a subclass widens it. */
2471
+ /** The validator's state for one field it is registered on; a subclass extends it. */
2048
2472
  declare interface ValidatorBindingState {
2049
2473
  run: number;
2050
- /** cancels the asynchronous run in flight over the field, absent while no run is waiting for its verdict */
2474
+ /** cancels the asynchronous run in flight over the field; undefined while no run is pending */
2051
2475
  abandon?: () => void;
2052
2476
  }
2053
2477
 
@@ -2060,9 +2484,11 @@ export declare namespace Validators {
2060
2484
  Required_2 as Required,
2061
2485
  RequiredOptions,
2062
2486
  Pattern,
2487
+ isEmptyValue,
2063
2488
  ValidationFunctionResult,
2064
2489
  ValidationFunction,
2065
2490
  ValidatorBindingState,
2491
+ ValidationErrorOptions,
2066
2492
  Validator,
2067
2493
  MinValue,
2068
2494
  MaxValue,
@@ -2086,39 +2512,38 @@ export declare class ValueChangedAction<T = any> extends FieldActionBase {
2086
2512
  }
2087
2513
 
2088
2514
  declare class ValueInRange<T = any> extends Validator {
2089
- constructor(minValue: T, maxValue: T, message?: RenderContentRef);
2515
+ constructor(minValue: T, maxValue: T, options?: ValidationErrorOptions);
2090
2516
  }
2091
2517
 
2092
2518
  /**
2093
- * An element seen as its data: the members of a group, or the rows of a list, as plain properties, and the element
2094
- * itself as `$`. See `view()`.
2519
+ * An element presented as its data: the members of a group, or the rows of a list, as plain properties, and the
2520
+ * element itself as `$`. See `view()`.
2095
2521
  */
2096
2522
  export declare type View<E extends FieldBase> = (E extends Group<infer F, any> ? GroupData<F> : E extends List<infer R, any> ? ListData<R> : unknown) & {
2097
2523
  readonly $: E;
2098
2524
  };
2099
2525
 
2100
2526
  /**
2101
- * The element seen as its data. A group's members and a list's rows are plain properties of the view - a field as
2102
- * its value, a container as its own view - and `$` is the element itself: `view.$.valid`,
2527
+ * Returns the element presented as its data. A group's members and a list's rows are plain properties of the view
2528
+ * (a field as its value, a container as its own view), and `$` is the element itself: `view.$.valid`,
2103
2529
  * `view.$.access = 'readonly'`, `view.$.registerAction(...)`.
2104
2530
  *
2105
- * A member reads what the element holds, by the rule `fullValue` follows: every member is there whatever its access,
2106
- * so a disabled field reads and writes like any other. Every read goes
2107
- * through the element's tracked state, so an effect reading `view.address.city` re-runs when that field changes and
2108
- * not when another one does.
2531
+ * A member reads what the element holds, as in `fullValue`: every member is present whatever its access, so a
2532
+ * disabled field reads and writes like any other. Every read goes through the element's tracked state, so an
2533
+ * effect that reads `view.address.city` re-runs when that field changes and not when another one does.
2109
2534
  *
2110
2535
  * A list's view is an array: it reads like one, and `push`, `pop`, `shift`, `unshift`, `splice`, `sort` and
2111
- * `reverse` are carried out as the list's own operations, so every row keeps its element and its state.
2536
+ * `reverse` are performed as the list's own operations, so every row keeps its element and its state.
2112
2537
  *
2113
- * One element has one view: `view(element) === view(element)`, and `view()` of a view hands it back.
2538
+ * One element has one view: `view(element) === view(element)`, and `view()` of a view returns the same view.
2114
2539
  */
2115
2540
  export declare function view<V extends View<any>>(of: V): V;
2116
2541
 
2117
2542
  export declare function view<E extends FieldBase>(element: E): View<E>;
2118
2543
 
2119
2544
  /**
2120
- * How a rendering layer shows a form element. It is presentation alone: what an element sends and whether it is
2121
- * validated are its `access`, and no visibility changes either.
2545
+ * How a rendering layer shows a form element. It affects presentation only: what an element sends and whether it
2546
+ * is validated are determined by `access`, and visibility changes neither.
2122
2547
  *
2123
2548
  * - `'full'`: rendered and shown
2124
2549
  * - `'invisible'`: rendered and keeps its space in the layout, but is not painted (`visibility: hidden`)
@@ -2143,3 +2568,15 @@ export declare class VisibilityChangingAction extends FieldActionBase {
2143
2568
  export declare const visibilityValues: readonly Visibility[];
2144
2569
 
2145
2570
  export { }
2571
+
2572
+
2573
+ declare module '@vue/reactivity' {
2574
+ /**
2575
+ * An element carries __v_skip, so ref() and reactive() hold it as it is. Listing it here makes their types do the
2576
+ * same: `ref([action])` is a `Ref<Action[]>` and `reactive({ form }).form` is the form's own type, where Vue's
2577
+ * unwrapping would otherwise produce a structural copy of the class without its non-public members.
2578
+ */
2579
+ interface RefUnwrapBailTypes {
2580
+ dynamicformsElement: FieldBase<any, any>;
2581
+ }
2582
+ }