@dynamicforms/vue-forms 2.0.3 → 3.0.0-alpha.2

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