@reformer/core 10.0.0 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { effect as i } from "@preact/signals-core";
2
2
  import { g as s } from "./signal-node-registry-tiwel-TV.js";
3
- import { d as f } from "./behaviors-value-lCpqicfa.js";
3
+ import { d as f } from "./behaviors-value-C7dSEhCc.js";
4
4
  function a(n, r, t) {
5
5
  return i(() => {
6
6
  const o = r(), e = s(n);
@@ -1,57 +1,46 @@
1
1
  import { effect as f } from "@preact/signals-core";
2
- const a = /* @__PURE__ */ new WeakMap();
3
- function h(e) {
4
- a.set(e, (a.get(e) ?? 0) + 1);
5
- }
6
- function y(e) {
7
- const n = a.get(e);
8
- n !== void 0 && (n <= 1 ? a.delete(e) : a.set(e, n - 1));
9
- }
10
- function E(e) {
11
- return a.has(e);
12
- }
13
- const m = "runOutsideEffect";
14
- function v(e, n) {
2
+ const d = "runOutsideEffect";
3
+ function i(e, n) {
15
4
  process.env.NODE_ENV !== "production" && console.error(`[${n}]`, e);
16
5
  }
17
- function p(e) {
6
+ function m(e) {
18
7
  return typeof e == "object" && e !== null && typeof e.then == "function";
19
8
  }
20
- function d(e, n) {
9
+ function v(e, n) {
21
10
  try {
22
11
  const t = e();
23
- p(t) && t.then(void 0, (r) => v(r, n));
12
+ m(t) && t.then(void 0, (r) => i(r, n));
24
13
  } catch (t) {
25
- v(t, n);
14
+ i(t, n);
26
15
  }
27
16
  }
28
- function D(e) {
17
+ function y(e) {
29
18
  return (...n) => {
30
- s(() => e(...n));
19
+ a(() => e(...n));
31
20
  };
32
21
  }
33
- function s(e) {
22
+ function a(e) {
34
23
  let n = !1;
35
24
  return queueMicrotask(() => {
36
- n || d(e, m);
25
+ n || v(e, d);
37
26
  }), () => {
38
27
  n = !0;
39
28
  };
40
29
  }
41
- function w(e, n) {
30
+ function h(e, n) {
42
31
  return () => {
43
- n(() => d(e, "safeDebouncedCallback"));
32
+ n(() => v(e, "safeDebouncedCallback"));
44
33
  };
45
34
  }
46
- function b(e, n, t, r) {
35
+ function k(e, n, t, r) {
47
36
  return f(() => {
48
37
  const u = e.map((c) => c.value);
49
38
  if (r?.when && !r.when(...u)) return;
50
- const o = t(...u);
51
- n.peek() !== o && (n.value = o);
39
+ const s = t(...u);
40
+ n.peek() !== s && (n.value = s);
52
41
  });
53
42
  }
54
- function F(e, n, t) {
43
+ function E(e, n, t) {
55
44
  return f(() => {
56
45
  const r = e.value;
57
46
  if (t?.when && !t.when()) return;
@@ -59,18 +48,18 @@ function F(e, n, t) {
59
48
  n.peek() !== u && (n.value = u);
60
49
  });
61
50
  }
62
- function x(e, n, t) {
51
+ function w(e, n, t) {
63
52
  let r = !0;
64
53
  return f(() => {
65
54
  const u = e.value;
66
55
  r && (r = !1, !t?.immediate) || n(u);
67
56
  });
68
57
  }
69
- function C(e, n) {
58
+ function b(e, n) {
70
59
  let t = !1;
71
60
  return f(() => {
72
61
  const r = e.value;
73
- t || s(() => {
62
+ t || a(() => {
74
63
  const u = n(r);
75
64
  if (e.peek() !== u) {
76
65
  t = !0;
@@ -83,66 +72,63 @@ function C(e, n) {
83
72
  });
84
73
  });
85
74
  }
86
- function O(e, n, t) {
75
+ function D(e, n, t) {
87
76
  const r = t?.resetValue ?? null;
88
77
  return f(() => {
89
78
  const u = n();
90
- s(() => {
79
+ a(() => {
91
80
  u && e.peek() !== r && (e.value = r);
92
81
  });
93
82
  });
94
83
  }
95
- function V(e, n, t) {
84
+ function F(e, n, t) {
96
85
  const r = t?.transform;
97
86
  let u = !1;
98
- const o = f(() => {
99
- const i = e.value;
100
- u || s(() => {
87
+ const s = f(() => {
88
+ const l = e.value;
89
+ u || a(() => {
101
90
  u = !0;
102
91
  try {
103
- const l = r ? r(i) : i;
104
- n.peek() !== l && (n.value = l);
92
+ const o = r ? r(l) : l;
93
+ n.peek() !== o && (n.value = o);
105
94
  } finally {
106
95
  u = !1;
107
96
  }
108
97
  });
109
98
  }), c = f(() => {
110
- const i = n.value;
111
- u || s(() => {
99
+ const l = n.value;
100
+ u || a(() => {
112
101
  u = !0;
113
102
  try {
114
- e.peek() !== i && (e.value = i);
103
+ e.peek() !== l && (e.value = l);
115
104
  } finally {
116
105
  u = !1;
117
106
  }
118
107
  });
119
108
  });
120
109
  return () => {
121
- o(), c();
110
+ s(), c();
122
111
  };
123
112
  }
124
- function N(e, n) {
113
+ function x(e, n) {
125
114
  let t = !0;
126
115
  return f(() => {
127
116
  if (e.forEach((r) => r.value), t) {
128
117
  t = !1;
129
118
  return;
130
119
  }
131
- s(() => n());
120
+ a(() => n());
132
121
  });
133
122
  }
134
123
  export {
135
- F as a,
136
- N as b,
137
- b as c,
138
- s as d,
139
- D as e,
140
- w as f,
141
- E as i,
142
- h as m,
143
- O as r,
144
- V as s,
145
- C as t,
146
- y as u,
147
- x as w
124
+ E as a,
125
+ x as b,
126
+ k as c,
127
+ a as d,
128
+ y as e,
129
+ h as f,
130
+ D as r,
131
+ F as s,
132
+ b as t,
133
+ w
148
134
  };
package/dist/behaviors.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { effect as O } from "@preact/signals-core";
2
- import { d as $, m as k, u as x, a as S, w as F, t as A, r as C, s as D, b as M } from "./behaviors-value-lCpqicfa.js";
3
- import { e as G } from "./behaviors-node-DUrqAqp1.js";
2
+ import { d as $, a as S, w as F, t as A, r as C, s as D, b as M } from "./behaviors-value-C7dSEhCc.js";
3
+ import { m as k, u as x } from "./derived-registry-CluZCQ7U.js";
4
+ import { e as G } from "./behaviors-node-DGEFMTQu.js";
4
5
  let p = null;
5
6
  function P(e) {
6
7
  if (!p)
@@ -18,11 +19,11 @@ function y() {
18
19
  }
19
20
  function T(e) {
20
21
  return {
21
- __run(t, n) {
22
- const o = { cleanups: [], model: t, form: n }, r = p;
22
+ __run(n, t) {
23
+ const o = { cleanups: [], model: n, form: t }, r = p;
23
24
  p = o;
24
25
  try {
25
- e({ model: t, form: n });
26
+ e({ model: n, form: t });
26
27
  } finally {
27
28
  p = r;
28
29
  }
@@ -32,112 +33,112 @@ function T(e) {
32
33
  }
33
34
  };
34
35
  }
35
- function m(e) {
36
+ function h(e) {
36
37
  s(O(e));
37
38
  }
38
39
  function _(e) {
39
40
  $(e);
40
41
  }
41
- const h = (e) => typeof e == "object" && e !== null && typeof e.peek == "function", B = (e) => Array.isArray(e) ? e : [e];
42
+ const m = (e) => typeof e == "object" && e !== null && typeof e.peek == "function", B = (e) => Array.isArray(e) ? e : [e];
42
43
  function E(e) {
43
- const t = {};
44
- for (const n of Object.keys(e)) {
45
- const o = e[n];
46
- t[n] = h(o) ? o.value : E(o);
44
+ const n = {};
45
+ for (const t of Object.keys(e)) {
46
+ const o = e[t];
47
+ n[t] = m(o) ? o.value : E(o);
47
48
  }
48
- return t;
49
+ return n;
49
50
  }
50
- function W(e, t) {
51
- for (const n of Object.keys(e)) {
52
- const o = e[n];
53
- h(o) ? o.value = t?.[n] : W(o, t?.[n] ?? {});
51
+ function W(e, n) {
52
+ for (const t of Object.keys(e)) {
53
+ const o = e[t];
54
+ m(o) ? o.value = n?.[t] : W(o, n?.[t] ?? {});
54
55
  }
55
56
  }
56
57
  function I(e) {
57
58
  if (!e) return;
58
- const { form: t } = y();
59
- return t.getFieldByPath(e);
59
+ const { form: n } = y();
60
+ return n.getFieldByPath(e);
60
61
  }
61
62
  function V(e) {
62
63
  return new Proxy(
63
64
  {},
64
65
  {
65
- get: (t, n) => {
66
- if (n === "$") return e;
67
- if (typeof n != "string") return;
68
- const o = e[n];
66
+ get: (n, t) => {
67
+ if (t === "$") return e;
68
+ if (typeof t != "string") return;
69
+ const o = e[t];
69
70
  if (o != null)
70
- return h(o) ? o.value : V(o);
71
+ return m(o) ? o.value : V(o);
71
72
  }
72
73
  }
73
74
  );
74
75
  }
75
76
  function j(e) {
76
- return (t) => {
77
+ return (n) => {
77
78
  try {
78
- t();
79
- } catch (n) {
80
- if (n instanceof Error && /cycle detected/i.test(n.message)) {
79
+ n();
80
+ } catch (t) {
81
+ if (t instanceof Error && /cycle detected/i.test(t.message)) {
81
82
  const o = e.__path ?? "?";
82
83
  throw new Error(
83
84
  `[@reformer/core/behaviors] compute("${o}"): расходящийся цикл пересчёта — взаимные compute/computeFrom без стабилизации. Проверьте зависимости или добавьте стабилизирующее условие (when) / разорвите цикл через peek.`
84
85
  );
85
86
  }
86
- throw n;
87
+ throw t;
87
88
  }
88
89
  };
89
90
  }
90
- function Q(e, t, n) {
91
+ function U(e, n, t) {
91
92
  k(e), s(() => x(e));
92
93
  const o = j(e);
93
- m(() => {
94
- if (n?.when && !n.when()) return;
95
- const r = t();
94
+ h(() => {
95
+ if (t?.when && !t.when()) return;
96
+ const r = n();
96
97
  e.peek() !== r && o(() => {
97
98
  e.value = r;
98
99
  });
99
100
  });
100
101
  }
101
- function U(e, t, n, o) {
102
- k(t), s(() => x(t));
103
- const r = j(t);
104
- m(() => {
102
+ function X(e, n, t, o) {
103
+ k(n), s(() => x(n));
104
+ const r = j(n);
105
+ h(() => {
105
106
  const c = e.map((f) => f.value);
106
107
  if (o?.when && !o.when(...c)) return;
107
- const i = n(...c);
108
- t.peek() !== i && r(() => {
109
- t.value = i;
108
+ const i = t(...c);
109
+ n.peek() !== i && r(() => {
110
+ n.value = i;
110
111
  });
111
112
  });
112
113
  }
113
- function X(e, t, n) {
114
- if (h(e) && h(t)) {
115
- s(S(e, t, n));
114
+ function Y(e, n, t) {
115
+ if (m(e) && m(n)) {
116
+ s(S(e, n, t));
116
117
  return;
117
118
  }
118
- const o = e, r = t;
119
- m(() => {
119
+ const o = e, r = n;
120
+ h(() => {
120
121
  const c = E(o);
121
- n?.when && !n.when() || _(() => W(r, c));
122
+ t?.when && !t.when() || _(() => W(r, c));
122
123
  });
123
124
  }
124
- function R(e, t, n) {
125
+ function R(e, n, t) {
125
126
  let o;
126
127
  const r = (c) => {
127
128
  o?.abort(), o = new AbortController();
128
129
  const { signal: i } = o;
129
- $(() => t(c, { signal: i }));
130
+ $(() => n(c, { signal: i }));
130
131
  };
131
- if (!n?.debounce)
132
- s(F(e, r, { immediate: n?.immediate }));
132
+ if (!t?.debounce)
133
+ s(F(e, r, { immediate: t?.immediate }));
133
134
  else {
134
135
  let c;
135
136
  const i = F(
136
137
  e,
137
138
  (f) => {
138
- c && clearTimeout(c), c = setTimeout(() => r(f), n.debounce);
139
+ c && clearTimeout(c), c = setTimeout(() => r(f), t.debounce);
139
140
  },
140
- { immediate: n?.immediate }
141
+ { immediate: t?.immediate }
141
142
  );
142
143
  s(() => {
143
144
  c && clearTimeout(c), i();
@@ -145,67 +146,67 @@ function R(e, t, n) {
145
146
  }
146
147
  s(() => o?.abort());
147
148
  }
148
- function q(e, t, n) {
149
+ function q(e, n, t) {
149
150
  for (const o of B(e))
150
- h(o) ? s(G(o, t, n)) : z(o, t, n);
151
+ m(o) ? s(G(o, n, t)) : z(o, n, t);
151
152
  }
152
- function Y(e, t, n) {
153
- q(e, () => !t(), n);
153
+ function Z(e, n, t) {
154
+ q(e, () => !n(), t);
154
155
  }
155
- function z(e, t, n) {
156
+ function z(e, n, t) {
156
157
  const o = I(e.__path);
157
- o && m(() => {
158
- const r = t();
158
+ o && h(() => {
159
+ const r = n();
159
160
  _(() => {
160
- r ? o.enable() : (o.disable(), n?.resetOnDisable && o.reset());
161
+ r ? o.enable() : (o.disable(), t?.resetOnDisable && o.reset());
161
162
  });
162
163
  });
163
164
  }
164
- function Z(e, t) {
165
- s(A(e, t));
165
+ function ee(e, n) {
166
+ s(A(e, n));
166
167
  }
167
- function ee(e, t, n) {
168
- s(C(e, t, n));
168
+ function te(e, n, t) {
169
+ s(C(e, n, t));
169
170
  }
170
- function ne(e, t, n) {
171
- s(D(e, t, n));
171
+ function ne(e, n, t) {
172
+ s(D(e, n, t));
172
173
  }
173
- function te(e, t) {
174
- s(M(e, t));
174
+ function oe(e, n) {
175
+ s(M(e, n));
175
176
  }
176
- function g(e, t) {
177
- return t.split(".").reduce((n, o) => n?.[o], e);
177
+ function g(e, n) {
178
+ return n.split(".").reduce((t, o) => t?.[o], e);
178
179
  }
179
180
  function N(e) {
180
181
  return new Proxy(
181
182
  {},
182
183
  {
183
- get(t, n) {
184
- if (!(typeof n == "symbol" || n === "then"))
184
+ get(n, t) {
185
+ if (!(typeof t == "symbol" || t === "then"))
185
186
  throw new Error(
186
187
  `[@reformer/core/behaviors] applyEach: форма строки массива "${e}" недоступна (form.${String(
187
- n
188
+ t
188
189
  )}) — массив не материализован в схеме формы. Per-row node-операции (enableWhen/updateComponentProps/reset) требуют узла { array, item } в схеме; value-операции (row.$.*: compute/copyFrom/transformValue) работают и без материализации.`
189
190
  );
190
191
  }
191
192
  }
192
193
  );
193
194
  }
194
- function H(e, t) {
195
- const { model: n, form: o } = y(), r = e.__path;
195
+ function H(e, n) {
196
+ const { model: t, form: o } = y(), r = e.__path;
196
197
  if (!r) return;
197
- const c = g(n, r);
198
+ const c = g(t, r);
198
199
  if (!c) return;
199
200
  const i = o.getFieldByPath(
200
201
  r
201
202
  ), f = i?.length, u = /* @__PURE__ */ new Map();
202
- m(() => {
203
+ h(() => {
203
204
  const d = f ? f.value : c.length, w = /* @__PURE__ */ new Set();
204
205
  for (let a = 0; a < d; a++) {
205
206
  const l = c.at(a);
206
207
  if (l != null && (w.add(l), !u.has(l))) {
207
208
  const b = i?.at?.(a) ?? N(r);
208
- u.set(l, t.__run(l, b));
209
+ u.set(l, n.__run(l, b));
209
210
  }
210
211
  }
211
212
  for (const [a, l] of u)
@@ -217,27 +218,27 @@ function H(e, t) {
217
218
  }
218
219
  function v(e) {
219
220
  if (e == null || typeof e != "object") return;
220
- const t = e;
221
- if (typeof t.at == "function" && typeof t.length == "number") {
222
- const n = t.length;
223
- for (let o = 0; o < n; o++) v(t.at(o));
221
+ const n = e;
222
+ if (typeof n.at == "function" && typeof n.length == "number") {
223
+ const t = n.length;
224
+ for (let o = 0; o < t; o++) v(n.at(o));
224
225
  return;
225
226
  }
226
- for (const n of Object.keys(e)) v(e[n]);
227
+ for (const t of Object.keys(e)) v(e[t]);
227
228
  }
228
- function oe(e, t) {
229
- const { model: n } = y(), o = e.__path;
229
+ function re(e, n) {
230
+ const { model: t } = y(), o = e.__path;
230
231
  if (!o) return;
231
- const r = g(n, o);
232
+ const r = g(t, o);
232
233
  r && H(
233
234
  e,
234
235
  T(({ model: c }) => {
235
- R(t(c), (i) => {
236
+ R(n(c), (i) => {
236
237
  if (i)
237
238
  for (let f = 0; f < r.length; f++) {
238
239
  const u = r.at(f);
239
240
  if (u && u !== c) {
240
- const d = t(u);
241
+ const d = n(u);
241
242
  d.peek() && (d.value = !1);
242
243
  }
243
244
  }
@@ -245,16 +246,16 @@ function oe(e, t) {
245
246
  })
246
247
  );
247
248
  }
248
- function re(e, t) {
249
- const { model: n } = y(), o = e.__path;
249
+ function ce(e, n) {
250
+ const { model: t } = y(), o = e.__path;
250
251
  if (!o) return;
251
- const r = g(n, o);
252
+ const r = g(t, o);
252
253
  if (!r) return;
253
254
  let c = !1, i = 0;
254
- m(() => {
255
+ h(() => {
255
256
  v(r), !c && (c = !0, _(() => {
256
257
  c = !1;
257
- const f = t(r.toArray());
258
+ const f = n(r.toArray());
258
259
  let u = !1;
259
260
  for (const { index: d, patch: w } of f) {
260
261
  const a = r.at(d);
@@ -269,33 +270,33 @@ function re(e, t) {
269
270
  }));
270
271
  });
271
272
  }
272
- function ce(e, t) {
273
- const { form: n } = y();
273
+ function ie(e, n) {
274
+ const { form: t } = y();
274
275
  for (const o of B(e)) {
275
276
  const r = o, c = r.__path;
276
277
  if (!c) continue;
277
- const i = n ? n.getFieldByPath(c) : void 0, f = i ? i.getProxy?.() ?? i : void 0;
278
- s(t.__run(V(r), f));
278
+ const i = t ? t.getFieldByPath(c) : void 0, f = i ? i.getProxy?.() ?? i : void 0;
279
+ s(n.__run(V(r), f));
279
280
  }
280
281
  }
281
282
  export {
282
- re as aggregateInto,
283
- ce as apply,
283
+ ce as aggregateInto,
284
+ ie as apply,
284
285
  H as applyEach,
285
- Q as compute,
286
- U as computeFrom,
287
- X as copyFrom,
286
+ U as compute,
287
+ X as computeFrom,
288
+ Y as copyFrom,
288
289
  _ as defer,
289
290
  T as defineFormBehavior,
290
- Y as disableWhen,
291
- m as effect,
291
+ Z as disableWhen,
292
+ h as effect,
292
293
  q as enableWhen,
293
- oe as exclusiveFlag,
294
+ re as exclusiveFlag,
294
295
  y as getScope,
295
296
  R as onChange,
296
297
  s as onDispose,
297
- ee as resetWhen,
298
- te as revalidateWhen,
298
+ te as resetWhen,
299
+ oe as revalidateWhen,
299
300
  ne as syncFields,
300
- Z as transformValue
301
+ ee as transformValue
301
302
  };
@@ -0,0 +1,16 @@
1
+ const t = /* @__PURE__ */ new WeakMap();
2
+ function n(e) {
3
+ t.set(e, (t.get(e) ?? 0) + 1);
4
+ }
5
+ function i(e) {
6
+ const r = t.get(e);
7
+ r !== void 0 && (r <= 1 ? t.delete(e) : t.set(e, r - 1));
8
+ }
9
+ function o(e) {
10
+ return t.has(e);
11
+ }
12
+ export {
13
+ o as i,
14
+ n as m,
15
+ i as u
16
+ };
@@ -0,0 +1,48 @@
1
+ import { FormModel } from '../../index';
2
+ import { ValidationSchema } from '../validation-schema';
3
+ import { ValidationStrategyKind } from '../validation-strategy';
4
+ export interface UseFormValidationArgs<T> {
5
+ /** Модель данных формы. */
6
+ model: FormModel<T>;
7
+ /** Схема валидации. **Стабильная ссылка** (module-level `const` / `useMemo`) — иначе ломается дедуп раннера. */
8
+ schema: ValidationSchema<T>;
9
+ /** Стратегия запуска. Default `'submit'`. */
10
+ strategy?: ValidationStrategyKind;
11
+ /** Debounce (мс) для live-фаз (`change` / live-часть `afterFirstSubmit`). */
12
+ debounce?: number;
13
+ /** Режим live-фазы для `afterFirstSubmit`. Default `'change'`. */
14
+ liveAfterSubmit?: 'change' | 'blur';
15
+ }
16
+ export interface UseFormValidationResult {
17
+ /** Полный прогон + раскрытие ошибок (`touch:true`); для `onSubmit`. Стабильная ссылка. */
18
+ submit: () => Promise<boolean>;
19
+ /** Алиас `submit` для не-submit сценариев. */
20
+ validate: () => Promise<boolean>;
21
+ /** Идёт ли прогон (submit или live) — для блокировки кнопки. */
22
+ isValidating: boolean;
23
+ }
24
+ /**
25
+ * Декларативный выбор стратегии валидации формы: одна точка вместо ручной разводки
26
+ * `validateModel`/`revalidateWhen`. Собирает стабильный {@link createFormValidation}-контроллер,
27
+ * армит реактивную стратегию на клиенте (`useEffect` → SSR-safe) и отдаёт `submit`/`isValidating`.
28
+ *
29
+ * Схема-валидации — **стабильная ссылка** (обязанность вызывающего): контроллер мемоизируется по
30
+ * `[model, schema, strategy, debounce, liveAfterSubmit]`.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * const validation = defineValidationSchema<Form>(({ model }) => { ... }); // module-level
35
+ *
36
+ * function MyForm() {
37
+ * const { submit, isValidating } = useFormValidation({
38
+ * model, schema: validation, strategy: 'afterFirstSubmit', debounce: 300,
39
+ * });
40
+ * const onSubmit = async (e: React.FormEvent) => {
41
+ * e.preventDefault();
42
+ * if (await submit()) await api.save(model.get());
43
+ * };
44
+ * return <form onSubmit={onSubmit}>{ ... }<button disabled={isValidating}>Отправить</button></form>;
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function useFormValidation<T>(args: UseFormValidationArgs<T>): UseFormValidationResult;
@@ -31,4 +31,6 @@ export { uniqueId } from './unique-id';
31
31
  export { useFormControl } from './hooks/useFormControl';
32
32
  export { useFormControlValue } from './hooks/useFormControlValue';
33
33
  export { useArrayLength } from './hooks/useArrayLength';
34
+ export { useFormValidation } from './hooks/use-form-validation';
35
+ export type { UseFormValidationArgs, UseFormValidationResult } from './hooks/use-form-validation';
34
36
  export type { FieldControlState, ArrayControlState } from './hooks/types';
@@ -84,10 +84,23 @@ export declare function defineValidationSchema<T>(schema: ValidationSchema<T>):
84
84
  * Инлайн-стрелка (`validateModel(model, ({ model }) => …)`) каждый раз создаёт НОВЫЙ прогон без дедупликации —
85
85
  * держите схемы в `const` / `defineValidationSchema`.
86
86
  *
87
+ * `options.touch` (§6): по завершении помечает `touched` ИМЕННО поля, которые схема проверяла
88
+ * (не всё поддерево). Ошибки становятся видимыми (`shouldShowError = invalid && (touched||dirty)`)
89
+ * без ручного `form.markAsTouched()`; при пошаговой валидации следующий шаг не показывается
90
+ * «тронутым» до ввода. Валидные проверенные поля тоже метятся — это безвредно (ошибка не покажется).
91
+ *
92
+ * @param model - Модель данных формы.
93
+ * @param schema - Схема валидации (стабильная ссылка).
94
+ * @param options - `{ touch }` — пометить провалидированные поля `touched` для показа ошибок.
95
+ *
87
96
  * @example
88
97
  * ```ts
89
- * const ok = await validateModel(model, step2Validation); // один шаг
90
- * const all = await validateModel(model, formValidation); // вся форма
98
+ * const ok = await validateModel(model, step2Validation); // один шаг
99
+ * const all = await validateModel(model, formValidation); // вся форма
100
+ * const stepOk = await validateModel(model, step2Validation, { touch: true }); // + показать ошибки шага
91
101
  * ```
92
102
  */
93
- export declare function validateModel<T>(model: FormModel<T>, schema: ValidationSchema<T>): Promise<boolean>;
103
+ export declare function validateModel<T>(model: FormModel<T>, schema: ValidationSchema<T>, options?: {
104
+ touch?: boolean;
105
+ }): Promise<boolean>;
106
+ export * from './validation-strategy';