@reformer/core 9.0.0-beta.2 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/behaviors-node-BMOI2JJF.js +26 -0
  2. package/dist/behaviors-value-lCpqicfa.js +148 -0
  3. package/dist/behaviors.d.ts +2 -133
  4. package/dist/behaviors.js +29 -28
  5. package/dist/{core/utils → form}/aggregate-signals.d.ts +2 -2
  6. package/dist/form/behaviors-node.d.ts +55 -0
  7. package/dist/form/behaviors.d.ts +133 -0
  8. package/dist/{core/utils → form}/create-form.d.ts +5 -4
  9. package/dist/{core/utils → form}/error-handler.d.ts +1 -1
  10. package/dist/{core → form}/factories/node-factory.d.ts +1 -1
  11. package/dist/{core/utils → form}/form-proxy-builder.d.ts +2 -2
  12. package/dist/{hooks → form/hooks}/types.d.ts +1 -1
  13. package/dist/{hooks → form/hooks}/useArrayLength.d.ts +1 -1
  14. package/dist/{hooks → form/hooks}/useFormControl.d.ts +3 -3
  15. package/dist/{hooks → form/hooks}/useFormControlValue.d.ts +2 -2
  16. package/dist/form/index.d.ts +36 -0
  17. package/dist/{core → form}/nodes/array-node.d.ts +1 -1
  18. package/dist/{core → form}/nodes/field-node.d.ts +1 -1
  19. package/dist/{core → form}/nodes/form-node.d.ts +1 -1
  20. package/dist/{core → form}/nodes/group-node.d.ts +2 -2
  21. package/dist/{core → form}/nodes/model-array-node.d.ts +2 -2
  22. package/dist/{core/utils → form}/signal-node-registry.d.ts +1 -1
  23. package/dist/{core/utils → form}/status-machine.d.ts +1 -1
  24. package/dist/{core/utils → form}/type-guards.d.ts +5 -5
  25. package/dist/{core/types/index.d.ts → form/types/contracts.d.ts} +11 -90
  26. package/dist/form/types/index.d.ts +91 -0
  27. package/dist/{core → form}/types/schema-node.d.ts +1 -1
  28. package/dist/{core → form}/types/validation-schema.d.ts +1 -1
  29. package/dist/{core/model/validate-model.d.ts → form/validate-model-core.d.ts} +25 -25
  30. package/dist/form/validate-model.d.ts +27 -0
  31. package/dist/form/validators.d.ts +6 -0
  32. package/dist/form-model-C8Fi83k4.js +439 -0
  33. package/dist/index.d.ts +11 -16
  34. package/dist/index.js +663 -1016
  35. package/dist/{core/model/behaviors.d.ts → state/behaviors-value.d.ts} +0 -53
  36. package/dist/state/form-model.d.ts +26 -0
  37. package/dist/state/index.d.ts +31 -0
  38. package/dist/{core/utils → state}/safe-effect.d.ts +4 -4
  39. package/dist/{core/model → state}/types.d.ts +14 -11
  40. package/dist/state.d.ts +2 -0
  41. package/dist/state.js +19 -0
  42. package/dist/validators/email.d.ts +1 -1
  43. package/dist/validators/future-date.d.ts +1 -1
  44. package/dist/validators/integer.d.ts +1 -1
  45. package/dist/validators/is-date.d.ts +1 -1
  46. package/dist/validators/is-number.d.ts +1 -1
  47. package/dist/validators/max-age.d.ts +1 -1
  48. package/dist/validators/max-date.d.ts +1 -1
  49. package/dist/validators/max-length.d.ts +1 -1
  50. package/dist/validators/max.d.ts +1 -1
  51. package/dist/validators/min-age.d.ts +1 -1
  52. package/dist/validators/min-date.d.ts +1 -1
  53. package/dist/validators/min-length.d.ts +1 -1
  54. package/dist/validators/min.d.ts +1 -1
  55. package/dist/validators/multiple-of.d.ts +1 -1
  56. package/dist/validators/non-negative.d.ts +1 -1
  57. package/dist/validators/non-zero.d.ts +1 -1
  58. package/dist/validators/past-date.d.ts +1 -1
  59. package/dist/validators/pattern.d.ts +1 -1
  60. package/dist/validators/phone.d.ts +1 -1
  61. package/dist/validators/required.d.ts +1 -1
  62. package/dist/validators/url.d.ts +1 -1
  63. package/dist/validators.d.ts +6 -6
  64. package/llms.txt +161 -147
  65. package/package.json +5 -1
  66. package/dist/behaviors-Br4Im38V.js +0 -263
  67. package/dist/core/model/form-model.d.ts +0 -18
  68. package/dist/core/model/index.d.ts +0 -12
  69. package/dist/core/utils/index.d.ts +0 -18
  70. /package/dist/{core → form}/factories/index.d.ts +0 -0
  71. /package/dist/{core/utils → form}/form-submitter.d.ts +0 -0
  72. /package/dist/{hooks → form/hooks}/useSignalSubscription.d.ts +0 -0
  73. /package/dist/{core → form}/types/deep-schema.d.ts +0 -0
  74. /package/dist/{core → form}/types/form-proxy.d.ts +0 -0
  75. /package/dist/{core/utils → form}/unique-id.d.ts +0 -0
  76. /package/dist/{core → form}/validation/index.d.ts +0 -0
  77. /package/dist/{core → form}/validation/validators/date-utils.d.ts +0 -0
  78. /package/dist/{core → form}/validation/validators/email.d.ts +0 -0
  79. /package/dist/{core → form}/validation/validators/future-date.d.ts +0 -0
  80. /package/dist/{core → form}/validation/validators/index.d.ts +0 -0
  81. /package/dist/{core → form}/validation/validators/integer.d.ts +0 -0
  82. /package/dist/{core → form}/validation/validators/is-date.d.ts +0 -0
  83. /package/dist/{core → form}/validation/validators/is-number.d.ts +0 -0
  84. /package/dist/{core → form}/validation/validators/max-age.d.ts +0 -0
  85. /package/dist/{core → form}/validation/validators/max-date.d.ts +0 -0
  86. /package/dist/{core → form}/validation/validators/max-length.d.ts +0 -0
  87. /package/dist/{core → form}/validation/validators/max.d.ts +0 -0
  88. /package/dist/{core → form}/validation/validators/min-age.d.ts +0 -0
  89. /package/dist/{core → form}/validation/validators/min-date.d.ts +0 -0
  90. /package/dist/{core → form}/validation/validators/min-length.d.ts +0 -0
  91. /package/dist/{core → form}/validation/validators/min.d.ts +0 -0
  92. /package/dist/{core → form}/validation/validators/multiple-of.d.ts +0 -0
  93. /package/dist/{core → form}/validation/validators/non-negative.d.ts +0 -0
  94. /package/dist/{core → form}/validation/validators/non-zero.d.ts +0 -0
  95. /package/dist/{core → form}/validation/validators/past-date.d.ts +0 -0
  96. /package/dist/{core → form}/validation/validators/pattern.d.ts +0 -0
  97. /package/dist/{core → form}/validation/validators/phone.d.ts +0 -0
  98. /package/dist/{core → form}/validation/validators/required.d.ts +0 -0
  99. /package/dist/{core → form}/validation/validators/url.d.ts +0 -0
  100. /package/dist/{core/utils → state}/derived-registry.d.ts +0 -0
  101. /package/dist/{core/utils → state}/subscription-manager.d.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  import { FormNode } from '../nodes/form-node';
2
- import { ConfigWithSchema, ConfigWithValue, UnknownRecord } from '../types';
2
+ import { ConfigWithSchema, ConfigWithValue, UnknownRecord } from '../types/index';
3
3
  /**
4
4
  * Фабрика для создания узлов формы.
5
5
  *
@@ -1,5 +1,5 @@
1
- import { FormNode } from '../nodes/form-node';
2
- import { FormProxy } from '../types/form-proxy';
1
+ import { FormNode } from './nodes/form-node';
2
+ import { FormProxy } from './types/form-proxy';
3
3
  /**
4
4
  * Создать Proxy для типобезопасного доступа к полям GroupNode
5
5
  *
@@ -1,4 +1,4 @@
1
- import { ValidationError } from '../core/types';
1
+ import { ValidationError } from '../types/index';
2
2
  /**
3
3
  * Состояние поля формы, возвращаемое хуком {@link useFormControl} для {@link FieldNode}.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { ArrayNode } from '../core/nodes/array-node';
1
+ import { ArrayNode } from '../nodes/array-node';
2
2
  /**
3
3
  * React-хук для подписки только на длину массива.
4
4
  *
@@ -1,6 +1,6 @@
1
- import { FieldNode } from '../core/nodes/field-node';
2
- import { ArrayNode } from '../core/nodes/array-node';
3
- import { FormValue } from '../core/types';
1
+ import { FieldNode } from '../nodes/field-node';
2
+ import { ArrayNode } from '../nodes/array-node';
3
+ import { FormValue } from '../types/index';
4
4
  import { FieldControlState, ArrayControlState } from './types';
5
5
  /**
6
6
  * React-хук для подписки на состояние {@link ArrayNode}.
@@ -1,5 +1,5 @@
1
- import { FieldNode } from '../core/nodes/field-node';
2
- import { FormValue } from '../core/types';
1
+ import { FieldNode } from '../nodes/field-node';
2
+ import { FormValue } from '../types/index';
3
3
  /**
4
4
  * React-хук для подписки только на значение поля.
5
5
  *
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Модуль `form` — доменный слой формы поверх state-субстрата (`model`).
3
+ *
4
+ * Ноды (value/touched/dirty/status/errors/componentProps), сборка формы из модели по идентичности
5
+ * сигнала (`createForm`), state-операции над нодами (`enableWhen`/`disableWhen`), in-form роутинг
6
+ * валидации (`validateFormModel`), submit/статус, React-хуки. Зависит от `model` (form→state
7
+ * разрешено); обратной зависимости нет.
8
+ *
9
+ * @group Form
10
+ * @module form
11
+ */
12
+ export { FormNode } from './nodes/form-node';
13
+ export type { SetValueOptions } from './nodes/form-node';
14
+ export { FieldNode } from './nodes/field-node';
15
+ export { GroupNode } from './nodes/group-node';
16
+ export { ArrayNode } from './nodes/array-node';
17
+ export { ModelArrayNode } from './nodes/model-array-node';
18
+ export type { ModelArrayControl } from './nodes/model-array-node';
19
+ export { createForm, createFormFromModel } from './create-form';
20
+ export type { CreateFormFromModelArgs } from './create-form';
21
+ export { validateModel, validateModelSync } from './validate-model-core';
22
+ export type { ModelValidator, ModelValidationResult } from './validate-model-core';
23
+ export { validateFormModel } from './validate-model';
24
+ export { enableWhen, disableWhen } from './behaviors-node';
25
+ export { FormErrorHandler, ErrorStrategy } from './error-handler';
26
+ export { registerSignalNode, getNodeForSignal } from './signal-node-registry';
27
+ export { FormSubmitter } from './form-submitter';
28
+ export type { SubmittableForm, SubmitOptions, SubmitResult } from './form-submitter';
29
+ export { FormStatusMachine } from './status-machine';
30
+ export type { StatusEvent } from './status-machine';
31
+ export { isFormNode, isFieldNode, isGroupNode, isArrayNode, getNodeType } from './type-guards';
32
+ export { uniqueId } from './unique-id';
33
+ export { useFormControl } from './hooks/useFormControl';
34
+ export { useFormControlValue } from './hooks/useFormControlValue';
35
+ export { useArrayLength } from './hooks/useArrayLength';
36
+ export type { FieldControlState, ArrayControlState } from './hooks/types';
@@ -1,6 +1,6 @@
1
1
  import { ReadonlySignal } from '@preact/signals-core';
2
2
  import { FormNode, SetValueOptions } from './form-node';
3
- import { FieldStatus, ValidationError } from '../types';
3
+ import { FieldStatus, ValidationError } from '../types/index';
4
4
  import { FormSchema } from '../types/deep-schema';
5
5
  import { FormProxy } from '../types/form-proxy';
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { ReadonlySignal } from '@preact/signals-core';
2
2
  import { FormNode, SetValueOptions } from './form-node';
3
- import { FieldConfig, FieldStatus, ValidationError } from '../types';
3
+ import { FieldConfig, FieldStatus, ValidationError } from '../types/index';
4
4
  /**
5
5
  * FieldNode - узел для отдельного поля формы
6
6
  *
@@ -1,5 +1,5 @@
1
1
  import { ReadonlySignal, Signal } from '@preact/signals-core';
2
- import { FieldStatus, ValidationError, ErrorFilterOptions } from '../types';
2
+ import { FieldStatus, ValidationError, ErrorFilterOptions } from '../types/index';
3
3
  /**
4
4
  * Опции для setValue
5
5
  * @group Nodes
@@ -1,8 +1,8 @@
1
1
  import { Signal, ReadonlySignal } from '@preact/signals-core';
2
2
  import { FormNode, SetValueOptions } from './form-node';
3
- import { ValidationError, FieldStatus, FormSchema, GroupNodeConfig, FormValue } from '../types';
3
+ import { ValidationError, FieldStatus, FormSchema, GroupNodeConfig, FormValue } from '../types/index';
4
4
  import { FormProxy } from '../types/form-proxy';
5
- import { SubmitOptions, SubmitResult } from '../utils/form-submitter';
5
+ import { SubmitOptions, SubmitResult } from '../form-submitter';
6
6
  /**
7
7
  * GroupNode - узел для группы полей
8
8
  *
@@ -1,7 +1,7 @@
1
1
  import { Signal, ReadonlySignal } from '@preact/signals-core';
2
2
  import { FormNode } from './form-node';
3
- import { FieldStatus, ValidationError } from '../types';
4
- import { FormModel } from '../model/types';
3
+ import { FieldStatus, ValidationError } from '../types/index';
4
+ import { FormModel } from '../../state/types';
5
5
  import { FormProxy } from '../types/form-proxy';
6
6
  /** Минимальный контракт реактивного массива модели, используемый узлом. */
7
7
  export interface ModelArrayControl<TItem extends object> {
@@ -1,5 +1,5 @@
1
1
  import { Signal } from '@preact/signals-core';
2
- import { FormNode } from '../nodes/form-node';
2
+ import { FormNode } from './nodes/form-node';
3
3
  /**
4
4
  * Связать сигнал модели с его нодой формы.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import { ReadonlySignal } from '@preact/signals-core';
2
- import { FieldStatus } from '../types';
2
+ import { FieldStatus } from './types/index';
3
3
  /**
4
4
  * События для State Machine
5
5
  */
@@ -1,8 +1,8 @@
1
- import { FormNode } from '../nodes/form-node';
2
- import { FieldNode } from '../nodes/field-node';
3
- import { GroupNode } from '../nodes/group-node';
4
- import { ArrayNode } from '../nodes/array-node';
5
- import { FormValue } from '../types';
1
+ import { FormNode } from './nodes/form-node';
2
+ import { FieldNode } from './nodes/field-node';
3
+ import { GroupNode } from './nodes/group-node';
4
+ import { ArrayNode } from './nodes/array-node';
5
+ import { FormValue } from './types/index';
6
6
  /**
7
7
  * Проверить, является ли значение любым FormNode
8
8
  *
@@ -1,5 +1,14 @@
1
- import { FormSchema } from './deep-schema';
2
- import { FormNode } from '../nodes/form-node';
1
+ /**
2
+ * Общие контракт-типы значения и валидации (state-слой).
3
+ *
4
+ * Эти типы нужны и headless-движку валидации данных (`validate-model-core`, `schema-node`,
5
+ * `error-handler` — state), и form-слою. Живут в `model/`, поэтому state их импортирует напрямую,
6
+ * а form-слой реэкспортирует из `form/types` (form→state разрешено). Так граница state⇏form не
7
+ * нарушается: общие контракты принадлежат нижнему слою.
8
+ *
9
+ * @group Types
10
+ * @module model/contracts
11
+ */
3
12
  /**
4
13
  * Represents any valid form value type
5
14
  * Use this instead of 'any' for form values to maintain type safety
@@ -95,91 +104,3 @@ export interface ErrorFilterOptions {
95
104
  * @category Core Types
96
105
  */
97
106
  export type FieldStatus = 'valid' | 'invalid' | 'pending' | 'disabled';
98
- export type { FieldConfig } from './deep-schema';
99
- export type { Validator, AsyncValidator, ConditionFn, ValidateOptions, ValidateAsyncOptions, } from './validation-schema';
100
- export type { FormSchema, ArrayConfig } from './deep-schema';
101
- export type { FormSchemaNode, SchemaArrayControl, SchemaValidator } from './schema-node';
102
- export type { FormControlsProxy, FormProxy, FormArrayProxy } from './form-proxy';
103
- /**
104
- * Конфигурация GroupNode.
105
- *
106
- * Под M1 группа создаётся из плоской {@link FormSchema} (дерево field-конфигов). Обёртка
107
- * `{ form }` сохранена для совместимости вызова, legacy behavior/validation-схемы удалены (Ф7).
108
- *
109
- * @group Types
110
- * @category Configuration Types
111
- */
112
- export interface GroupNodeConfig<T> {
113
- /** Схема структуры формы (поля и их конфигурация) */
114
- form: FormSchema<T>;
115
- }
116
- /**
117
- * Тип для Record с unknown значениями
118
- * Используется вместо инлайнового `Record<string, unknown>`
119
- * @internal
120
- */
121
- export type UnknownRecord = Record<string, unknown>;
122
- /**
123
- * Интерфейс для узлов с методом applyValidationSchema
124
- * @internal
125
- */
126
- export interface WithValidationSchema {
127
- applyValidationSchema(schemaFn: unknown): void;
128
- }
129
- /**
130
- * Интерфейс для узлов с методом applyBehaviorSchema
131
- * @internal
132
- */
133
- export interface WithBehaviorSchema {
134
- applyBehaviorSchema(schemaFn: unknown): void;
135
- }
136
- /**
137
- * Интерфейс для узлов, похожих на ArrayNode (с методом at)
138
- * Используется для duck typing при обходе путей
139
- * @internal
140
- */
141
- export interface ArrayNodeLike {
142
- at(index: number): FormNode<unknown> | undefined;
143
- length: unknown;
144
- }
145
- /**
146
- * Конфиг с полем schema (для ArrayConfig)
147
- * @internal
148
- */
149
- export interface ConfigWithSchema {
150
- schema: unknown;
151
- initialItems?: unknown[];
152
- }
153
- /**
154
- * Конфиг с полем value (для извлечения значений)
155
- * @internal
156
- */
157
- export interface ConfigWithValue {
158
- value: unknown;
159
- }
160
- /**
161
- * Тип для путей к полям (field paths)
162
- * Используется в навигации по полям вместо any
163
- * @internal
164
- */
165
- export type FieldPathSegment = {
166
- key: string;
167
- index?: number;
168
- };
169
- /**
170
- * Тип для коллбэков и обработчиков событий
171
- * Используется вместо (...args: any[]) => any
172
- * @internal
173
- */
174
- export type UnknownCallback = (...args: unknown[]) => unknown;
175
- /**
176
- * Тип для проверки на функцию в conditional types
177
- * Используется вместо Function для type narrowing
178
- * @internal
179
- */
180
- export type AnyFunction = (...args: never[]) => unknown;
181
- /**
182
- * Тип для результатов загрузки ресурсов
183
- * @internal
184
- */
185
- export type ResourceLoadResult = unknown;
@@ -0,0 +1,91 @@
1
+ import { FormSchema } from './deep-schema';
2
+ import { FormNode } from '../nodes/form-node';
3
+ export type { FormValue, UnknownFormValue, ValidatorFn, AsyncValidatorOptions, AsyncValidatorFn, ValidationError, ErrorFilterOptions, FieldStatus, } from './contracts';
4
+ export type { FieldConfig } from './deep-schema';
5
+ export type { Validator, AsyncValidator, ConditionFn, ValidateOptions, ValidateAsyncOptions, } from './validation-schema';
6
+ export type { FormSchema, ArrayConfig } from './deep-schema';
7
+ export type { FormSchemaNode, SchemaArrayControl, SchemaValidator } from './schema-node';
8
+ export type { FormControlsProxy, FormProxy, FormArrayProxy } from './form-proxy';
9
+ /**
10
+ * Конфигурация GroupNode.
11
+ *
12
+ * Под M1 группа создаётся из плоской {@link FormSchema} (дерево field-конфигов). Обёртка
13
+ * `{ form }` сохранена для совместимости вызова, legacy behavior/validation-схемы удалены (Ф7).
14
+ *
15
+ * @group Types
16
+ * @category Configuration Types
17
+ */
18
+ export interface GroupNodeConfig<T> {
19
+ /** Схема структуры формы (поля и их конфигурация) */
20
+ form: FormSchema<T>;
21
+ }
22
+ /**
23
+ * Тип для Record с unknown значениями
24
+ * Используется вместо инлайнового `Record<string, unknown>`
25
+ * @internal
26
+ */
27
+ export type UnknownRecord = Record<string, unknown>;
28
+ /**
29
+ * Интерфейс для узлов с методом applyValidationSchema
30
+ * @internal
31
+ */
32
+ export interface WithValidationSchema {
33
+ applyValidationSchema(schemaFn: unknown): void;
34
+ }
35
+ /**
36
+ * Интерфейс для узлов с методом applyBehaviorSchema
37
+ * @internal
38
+ */
39
+ export interface WithBehaviorSchema {
40
+ applyBehaviorSchema(schemaFn: unknown): void;
41
+ }
42
+ /**
43
+ * Интерфейс для узлов, похожих на ArrayNode (с методом at)
44
+ * Используется для duck typing при обходе путей
45
+ * @internal
46
+ */
47
+ export interface ArrayNodeLike {
48
+ at(index: number): FormNode<unknown> | undefined;
49
+ length: unknown;
50
+ }
51
+ /**
52
+ * Конфиг с полем schema (для ArrayConfig)
53
+ * @internal
54
+ */
55
+ export interface ConfigWithSchema {
56
+ schema: unknown;
57
+ initialItems?: unknown[];
58
+ }
59
+ /**
60
+ * Конфиг с полем value (для извлечения значений)
61
+ * @internal
62
+ */
63
+ export interface ConfigWithValue {
64
+ value: unknown;
65
+ }
66
+ /**
67
+ * Тип для путей к полям (field paths)
68
+ * Используется в навигации по полям вместо any
69
+ * @internal
70
+ */
71
+ export type FieldPathSegment = {
72
+ key: string;
73
+ index?: number;
74
+ };
75
+ /**
76
+ * Тип для коллбэков и обработчиков событий
77
+ * Используется вместо (...args: any[]) => any
78
+ * @internal
79
+ */
80
+ export type UnknownCallback = (...args: unknown[]) => unknown;
81
+ /**
82
+ * Тип для проверки на функцию в conditional types
83
+ * Используется вместо Function для type narrowing
84
+ * @internal
85
+ */
86
+ export type AnyFunction = (...args: never[]) => unknown;
87
+ /**
88
+ * Тип для результатов загрузки ресурсов
89
+ * @internal
90
+ */
91
+ export type ResourceLoadResult = unknown;
@@ -1,5 +1,5 @@
1
1
  import { ComponentType } from 'react';
2
- import { ValidationError } from './index';
2
+ import { ValidationError } from './contracts';
3
3
  /**
4
4
  * Валидатор поля схемы. Узел хранит validators гетерогенно: движок `validate*` вызывает их как
5
5
  * `(value, scope, root)`, но сюда кладут любой контракт — `ValidatorFn` (value),
@@ -1,5 +1,5 @@
1
1
  import { FormValue, ValidationError } from './index';
2
- import { FormModel } from '../model/types';
2
+ import { FormModel } from '../../state/types';
3
3
  /**
4
4
  * Чистый синхронный валидатор поля.
5
5
  *
@@ -1,6 +1,6 @@
1
- import { ValidationError } from '../types';
2
- import { FormSchemaNode } from '../types/schema-node';
3
- import { FormModel } from './types';
1
+ import { ValidationError } from './types/contracts';
2
+ import { FormSchemaNode } from './types/schema-node';
3
+ import { FormModel, PathAwareSignal } from '../state/types';
4
4
  /**
5
5
  * Валидатор слоя **данных**. `value` — значение поля; `model` — ближайший scope (под-модель элемента
6
6
  * массива или корень); `root` — корневая модель.
@@ -21,6 +21,26 @@ export interface ModelValidationResult {
21
21
  /** Ключ — путь поля (`'coBorrowers.0.relationship'`). Только поля с ошибками. */
22
22
  errors: Record<string, ValidationError[]>;
23
23
  }
24
+ export interface FieldTask {
25
+ signal: PathAwareSignal<unknown>;
26
+ validators: ModelValidator[];
27
+ scope: unknown;
28
+ }
29
+ /** Результат обхода схемы: что валидировать и что очистить. */
30
+ export interface CollectResult {
31
+ /** Активные поля с валидаторами (прогоняются). */
32
+ tasks: FieldTask[];
33
+ /** Сигналы полей в ВЫКЛЮЧЕННЫХ ветках — их ошибки нужно очистить (`setErrors([])`). */
34
+ clearSignals: PathAwareSignal<unknown>[];
35
+ }
36
+ /** Один обход схемы → задачи (активные) + сигналы на очистку (выключенные ветки). */
37
+ export declare function collect(model: unknown, schema: unknown): CollectResult;
38
+ /**
39
+ * Есть ли среди собранных ошибок блокирующие. Ошибка с `severity: 'warning'` показывается,
40
+ * но НЕ блокирует submit (см. {@link ValidationError.severity} — 'warning' allows submission),
41
+ * поэтому `valid` выводится из наличия блокирующих ошибок, а не из общего количества ошибок.
42
+ */
43
+ export declare const hasBlockingErrors: (errors: Record<string, ValidationError[]>) => boolean;
24
44
  /**
25
45
  * Синхронная headless-валидация данных. Асинхронные валидаторы пропускаются.
26
46
  *
@@ -48,25 +68,5 @@ export declare function validateModelSync<T>(model: FormModel<T>, schema: FormSc
48
68
  * ```
49
69
  */
50
70
  export declare function validateModel<T>(model: FormModel<T>, schema: FormSchemaNode): Promise<ModelValidationResult>;
51
- /**
52
- * In-form валидация: прогоняет {@link validateModel} и роутит ошибки в ноды формы
53
- * (через реестр сигнал→нода): `node.setErrors(errors[path] ?? [])` — заодно очищает прошедшие поля
54
- * И поля выключенных веток (`{ when, children }` с ложным условием). Дерево обходится ОДИН раз.
55
- *
56
- * @group Model
57
- * @param model - Модель данных ({@link FormModel}) — источник значений полей.
58
- * @param schema - Единая схема формы (та же, что передавалась в `createForm`).
59
- * @returns {@link ModelValidationResult} — `valid` + ошибки по пути поля; побочный эффект — ошибки
60
- * разведены по нодам формы.
61
- * @remarks Поля, не материализованные в форме (элементы массива — строятся per-item), не роутятся
62
- * в родительскую форму; их ошибки доступны в возвращаемом результате по пути.
63
- *
64
- * @example Валидация перед submit (ошибки показываются в UI автоматически)
65
- * ```typescript
66
- * const form = createForm({ model, schema });
67
- * form.touchAll();
68
- * const res = await validateFormModel(model, schema);
69
- * if (res.valid) await api.save(model.get());
70
- * ```
71
- */
72
- export declare function validateFormModel<T>(model: FormModel<T>, schema: FormSchemaNode): Promise<ModelValidationResult>;
71
+ /** Прогон задач (sync + async): возвращает ошибки по пути. */
72
+ export declare function runTasks(tasks: FieldTask[], model: unknown): Promise<Record<string, ValidationError[]>>;
@@ -0,0 +1,27 @@
1
+ import { FormSchemaNode } from './types/schema-node';
2
+ import { FormModel } from '../state/types';
3
+ import { ModelValidationResult } from './validate-model-core';
4
+ export { validateModel, validateModelSync } from './validate-model-core';
5
+ export type { ModelValidator, ModelValidationResult } from './validate-model-core';
6
+ /**
7
+ * In-form валидация: прогоняет {@link validateModel} и роутит ошибки в ноды формы
8
+ * (через реестр сигнал→нода): `node.setErrors(errors[path] ?? [])` — заодно очищает прошедшие поля
9
+ * И поля выключенных веток (`{ when, children }` с ложным условием). Дерево обходится ОДИН раз.
10
+ *
11
+ * @group Model
12
+ * @param model - Модель данных ({@link FormModel}) — источник значений полей.
13
+ * @param schema - Единая схема формы (та же, что передавалась в `createForm`).
14
+ * @returns {@link ModelValidationResult} — `valid` + ошибки по пути поля; побочный эффект — ошибки
15
+ * разведены по нодам формы.
16
+ * @remarks Поля, не материализованные в форме (элементы массива — строятся per-item), не роутятся
17
+ * в родительскую форму; их ошибки доступны в возвращаемом результате по пути.
18
+ *
19
+ * @example Валидация перед submit (ошибки показываются в UI автоматически)
20
+ * ```typescript
21
+ * const form = createForm({ model, schema });
22
+ * form.touchAll();
23
+ * const res = await validateFormModel(model, schema);
24
+ * if (res.valid) await api.save(model.get());
25
+ * ```
26
+ */
27
+ export declare function validateFormModel<T>(model: FormModel<T>, schema: FormSchemaNode): Promise<ModelValidationResult>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-export validators from the main index to ensure single module instance.
3
+ * This prevents static registry isolation issues when consuming the library.
4
+ */
5
+ export { validators as default } from '../index';
6
+ export * from './validation/index';