@reformer/core 1.0.0-beta.3

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 (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/dist/behaviors.d.ts +2 -0
  4. package/dist/behaviors.js +230 -0
  5. package/dist/core/behavior/behavior-applicator.d.ts +71 -0
  6. package/dist/core/behavior/behavior-applicator.js +92 -0
  7. package/dist/core/behavior/behavior-context.d.ts +29 -0
  8. package/dist/core/behavior/behavior-context.js +38 -0
  9. package/dist/core/behavior/behavior-registry.d.ts +97 -0
  10. package/dist/core/behavior/behavior-registry.js +198 -0
  11. package/dist/core/behavior/behaviors/compute-from.d.ts +41 -0
  12. package/dist/core/behavior/behaviors/compute-from.js +84 -0
  13. package/dist/core/behavior/behaviors/copy-from.d.ts +31 -0
  14. package/dist/core/behavior/behaviors/copy-from.js +64 -0
  15. package/dist/core/behavior/behaviors/enable-when.d.ts +49 -0
  16. package/dist/core/behavior/behaviors/enable-when.js +81 -0
  17. package/dist/core/behavior/behaviors/index.d.ts +11 -0
  18. package/dist/core/behavior/behaviors/index.js +11 -0
  19. package/dist/core/behavior/behaviors/reset-when.d.ts +51 -0
  20. package/dist/core/behavior/behaviors/reset-when.js +63 -0
  21. package/dist/core/behavior/behaviors/revalidate-when.d.ts +30 -0
  22. package/dist/core/behavior/behaviors/revalidate-when.js +51 -0
  23. package/dist/core/behavior/behaviors/sync-fields.d.ts +28 -0
  24. package/dist/core/behavior/behaviors/sync-fields.js +66 -0
  25. package/dist/core/behavior/behaviors/transform-value.d.ts +120 -0
  26. package/dist/core/behavior/behaviors/transform-value.js +110 -0
  27. package/dist/core/behavior/behaviors/watch-field.d.ts +35 -0
  28. package/dist/core/behavior/behaviors/watch-field.js +56 -0
  29. package/dist/core/behavior/compose-behavior.d.ts +106 -0
  30. package/dist/core/behavior/compose-behavior.js +166 -0
  31. package/dist/core/behavior/create-field-path.d.ts +20 -0
  32. package/dist/core/behavior/create-field-path.js +69 -0
  33. package/dist/core/behavior/index.d.ts +12 -0
  34. package/dist/core/behavior/index.js +17 -0
  35. package/dist/core/behavior/types.d.ts +152 -0
  36. package/dist/core/behavior/types.js +7 -0
  37. package/dist/core/context/form-context-impl.d.ts +29 -0
  38. package/dist/core/context/form-context-impl.js +37 -0
  39. package/dist/core/factories/index.d.ts +6 -0
  40. package/dist/core/factories/index.js +6 -0
  41. package/dist/core/factories/node-factory.d.ts +209 -0
  42. package/dist/core/factories/node-factory.js +281 -0
  43. package/dist/core/nodes/array-node.d.ts +308 -0
  44. package/dist/core/nodes/array-node.js +534 -0
  45. package/dist/core/nodes/field-node.d.ts +269 -0
  46. package/dist/core/nodes/field-node.js +510 -0
  47. package/dist/core/nodes/form-node.d.ts +342 -0
  48. package/dist/core/nodes/form-node.js +343 -0
  49. package/dist/core/nodes/group-node/field-registry.d.ts +191 -0
  50. package/dist/core/nodes/group-node/field-registry.js +215 -0
  51. package/dist/core/nodes/group-node/index.d.ts +11 -0
  52. package/dist/core/nodes/group-node/index.js +11 -0
  53. package/dist/core/nodes/group-node/proxy-builder.d.ts +71 -0
  54. package/dist/core/nodes/group-node/proxy-builder.js +161 -0
  55. package/dist/core/nodes/group-node/state-manager.d.ts +184 -0
  56. package/dist/core/nodes/group-node/state-manager.js +265 -0
  57. package/dist/core/nodes/group-node.d.ts +494 -0
  58. package/dist/core/nodes/group-node.js +770 -0
  59. package/dist/core/types/deep-schema.d.ts +78 -0
  60. package/dist/core/types/deep-schema.js +11 -0
  61. package/dist/core/types/field-path.d.ts +42 -0
  62. package/dist/core/types/field-path.js +4 -0
  63. package/dist/core/types/form-context.d.ts +83 -0
  64. package/dist/core/types/form-context.js +25 -0
  65. package/dist/core/types/group-node-proxy.d.ts +135 -0
  66. package/dist/core/types/group-node-proxy.js +31 -0
  67. package/dist/core/types/index.d.ts +163 -0
  68. package/dist/core/types/index.js +4 -0
  69. package/dist/core/types/validation-schema.d.ts +104 -0
  70. package/dist/core/types/validation-schema.js +10 -0
  71. package/dist/core/utils/create-form.d.ts +61 -0
  72. package/dist/core/utils/create-form.js +24 -0
  73. package/dist/core/utils/debounce.d.ts +160 -0
  74. package/dist/core/utils/debounce.js +197 -0
  75. package/dist/core/utils/error-handler.d.ts +180 -0
  76. package/dist/core/utils/error-handler.js +226 -0
  77. package/dist/core/utils/field-path-navigator.d.ts +240 -0
  78. package/dist/core/utils/field-path-navigator.js +374 -0
  79. package/dist/core/utils/index.d.ts +14 -0
  80. package/dist/core/utils/index.js +14 -0
  81. package/dist/core/utils/registry-helpers.d.ts +50 -0
  82. package/dist/core/utils/registry-helpers.js +79 -0
  83. package/dist/core/utils/registry-stack.d.ts +69 -0
  84. package/dist/core/utils/registry-stack.js +86 -0
  85. package/dist/core/utils/resources.d.ts +41 -0
  86. package/dist/core/utils/resources.js +69 -0
  87. package/dist/core/utils/subscription-manager.d.ts +180 -0
  88. package/dist/core/utils/subscription-manager.js +214 -0
  89. package/dist/core/utils/type-guards.d.ts +116 -0
  90. package/dist/core/utils/type-guards.js +169 -0
  91. package/dist/core/validation/core/apply-when.d.ts +28 -0
  92. package/dist/core/validation/core/apply-when.js +41 -0
  93. package/dist/core/validation/core/apply.d.ts +63 -0
  94. package/dist/core/validation/core/apply.js +38 -0
  95. package/dist/core/validation/core/index.d.ts +8 -0
  96. package/dist/core/validation/core/index.js +8 -0
  97. package/dist/core/validation/core/validate-async.d.ts +42 -0
  98. package/dist/core/validation/core/validate-async.js +45 -0
  99. package/dist/core/validation/core/validate-tree.d.ts +35 -0
  100. package/dist/core/validation/core/validate-tree.js +37 -0
  101. package/dist/core/validation/core/validate.d.ts +32 -0
  102. package/dist/core/validation/core/validate.js +38 -0
  103. package/dist/core/validation/field-path.d.ts +43 -0
  104. package/dist/core/validation/field-path.js +147 -0
  105. package/dist/core/validation/index.d.ts +21 -0
  106. package/dist/core/validation/index.js +33 -0
  107. package/dist/core/validation/validate-form.d.ts +85 -0
  108. package/dist/core/validation/validate-form.js +152 -0
  109. package/dist/core/validation/validation-applicator.d.ts +89 -0
  110. package/dist/core/validation/validation-applicator.js +217 -0
  111. package/dist/core/validation/validation-context.d.ts +47 -0
  112. package/dist/core/validation/validation-context.js +75 -0
  113. package/dist/core/validation/validation-registry.d.ts +156 -0
  114. package/dist/core/validation/validation-registry.js +298 -0
  115. package/dist/core/validation/validators/array-validators.d.ts +63 -0
  116. package/dist/core/validation/validators/array-validators.js +86 -0
  117. package/dist/core/validation/validators/date.d.ts +38 -0
  118. package/dist/core/validation/validators/date.js +117 -0
  119. package/dist/core/validation/validators/email.d.ts +44 -0
  120. package/dist/core/validation/validators/email.js +60 -0
  121. package/dist/core/validation/validators/index.d.ts +14 -0
  122. package/dist/core/validation/validators/index.js +14 -0
  123. package/dist/core/validation/validators/max-length.d.ts +45 -0
  124. package/dist/core/validation/validators/max-length.js +60 -0
  125. package/dist/core/validation/validators/max.d.ts +45 -0
  126. package/dist/core/validation/validators/max.js +60 -0
  127. package/dist/core/validation/validators/min-length.d.ts +45 -0
  128. package/dist/core/validation/validators/min-length.js +60 -0
  129. package/dist/core/validation/validators/min.d.ts +45 -0
  130. package/dist/core/validation/validators/min.js +60 -0
  131. package/dist/core/validation/validators/number.d.ts +38 -0
  132. package/dist/core/validation/validators/number.js +90 -0
  133. package/dist/core/validation/validators/pattern.d.ts +47 -0
  134. package/dist/core/validation/validators/pattern.js +62 -0
  135. package/dist/core/validation/validators/phone.d.ts +34 -0
  136. package/dist/core/validation/validators/phone.js +58 -0
  137. package/dist/core/validation/validators/required.d.ts +48 -0
  138. package/dist/core/validation/validators/required.js +69 -0
  139. package/dist/core/validation/validators/url.d.ts +29 -0
  140. package/dist/core/validation/validators/url.js +55 -0
  141. package/dist/create-field-path-CdPF3lIK.js +704 -0
  142. package/dist/hooks/useFormControl.d.ts +48 -0
  143. package/dist/hooks/useFormControl.js +298 -0
  144. package/dist/index.d.ts +10 -0
  145. package/dist/index.js +8 -0
  146. package/dist/node-factory-D7DOnSSN.js +3200 -0
  147. package/dist/validators.d.ts +2 -0
  148. package/dist/validators.js +298 -0
  149. package/llms.txt +847 -0
  150. package/package.json +86 -0
@@ -0,0 +1,494 @@
1
+ /**
2
+ * GroupNode - узел группы полей формы
3
+ *
4
+ * Представляет группу полей (объект), где каждое поле может быть:
5
+ * - FieldNode (простое поле)
6
+ * - GroupNode (вложенная группа)
7
+ * - ArrayNode (массив форм)
8
+ *
9
+ * Наследует от FormNode и реализует все его абстрактные методы
10
+ *
11
+ * @group Nodes
12
+ */
13
+ import type { ReadonlySignal } from '@preact/signals-core';
14
+ import { FormNode, type SetValueOptions } from './form-node';
15
+ import type { ValidationError, FieldStatus, ValidationSchemaFn, ValidatorRegistration, FormSchema, GroupNodeConfig, FormValue } from '../types';
16
+ import type { GroupNodeWithControls } from '../types/group-node-proxy';
17
+ import type { BehaviorSchemaFn } from '../behavior/types';
18
+ import { FieldRegistry } from './group-node/field-registry';
19
+ /**
20
+ * GroupNode - узел для группы полей
21
+ *
22
+ * Поддерживает два API:
23
+ * 1. Старый API (только schema) - обратная совместимость
24
+ * 2. Новый API (config с form, behavior, validation) - автоматическое применение схем
25
+ *
26
+ * @group Nodes
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // 1. Старый способ (обратная совместимость)
31
+ * const simpleForm = new GroupNode({
32
+ * email: { value: '', component: Input },
33
+ * password: { value: '', component: Input },
34
+ * });
35
+ *
36
+ * // 2. Новый способ (с behavior и validation схемами)
37
+ * const fullForm = new GroupNode({
38
+ * form: {
39
+ * email: { value: '', component: Input },
40
+ * password: { value: '', component: Input },
41
+ * },
42
+ * behavior: (path) => {
43
+ * computeFrom(path.email, [path.email], (values) => values[0]?.trim());
44
+ * },
45
+ * validation: (path) => {
46
+ * required(path.email, { message: 'Email обязателен' });
47
+ * email(path.email);
48
+ * required(path.password);
49
+ * minLength(path.password, 8);
50
+ * },
51
+ * });
52
+ *
53
+ * // Прямой доступ к полям через Proxy
54
+ * fullForm.email.setValue('test@mail.com');
55
+ * await fullForm.validate();
56
+ * console.log(fullForm.valid.value); // true
57
+ * ```
58
+ */
59
+ export declare class GroupNode<T> extends FormNode<T> {
60
+ id: string;
61
+ /**
62
+ * Реестр полей формы
63
+ * Использует FieldRegistry для инкапсуляции логики управления коллекцией полей
64
+ */
65
+ private fieldRegistry;
66
+ /**
67
+ * Строитель Proxy для типобезопасного доступа к полям
68
+ * Использует ProxyBuilder для создания Proxy с расширенной функциональностью
69
+ */
70
+ private proxyBuilder;
71
+ /**
72
+ * Менеджер состояния формы
73
+ * Инкапсулирует всю логику создания и управления сигналами состояния
74
+ * Извлечен из GroupNode для соблюдения SRP
75
+ */
76
+ private stateManager;
77
+ /**
78
+ * Менеджер подписок для централизованного cleanup
79
+ * Использует SubscriptionManager вместо массива для управления подписками
80
+ */
81
+ private disposers;
82
+ /**
83
+ * Ссылка на Proxy-инстанс для использования в BehaviorContext
84
+ * Устанавливается в конструкторе до применения behavior schema
85
+ */
86
+ private _proxyInstance?;
87
+ /**
88
+ * Навигатор для работы с путями к полям
89
+ * Использует композицию вместо дублирования логики парсинга путей
90
+ */
91
+ private readonly pathNavigator;
92
+ /**
93
+ * Фабрика для создания узлов формы
94
+ * Использует композицию для централизованного создания FieldNode/GroupNode/ArrayNode
95
+ */
96
+ private readonly nodeFactory;
97
+ /**
98
+ * Реестр валидаторов для этой формы
99
+ * Использует композицию вместо глобального Singleton
100
+ * Обеспечивает полную изоляцию форм друг от друга
101
+ */
102
+ private readonly validationRegistry;
103
+ /**
104
+ * Реестр behaviors для этой формы
105
+ * Использует композицию вместо глобального Singleton
106
+ * Обеспечивает полную изоляцию форм друг от друга
107
+ */
108
+ private readonly behaviorRegistry;
109
+ /**
110
+ * Аппликатор для применения валидаторов к форме
111
+ * Извлечен из GroupNode для соблюдения SRP
112
+ * Использует композицию для управления процессом валидации
113
+ */
114
+ private readonly validationApplicator;
115
+ /**
116
+ * Аппликатор для применения behavior схемы к форме
117
+ * Извлечен из GroupNode для соблюдения SRP
118
+ * Использует композицию для управления процессом применения behaviors
119
+ */
120
+ private readonly behaviorApplicator;
121
+ readonly value: ReadonlySignal<T>;
122
+ readonly valid: ReadonlySignal<boolean>;
123
+ readonly invalid: ReadonlySignal<boolean>;
124
+ readonly touched: ReadonlySignal<boolean>;
125
+ readonly dirty: ReadonlySignal<boolean>;
126
+ readonly pending: ReadonlySignal<boolean>;
127
+ readonly errors: ReadonlySignal<ValidationError[]>;
128
+ readonly status: ReadonlySignal<FieldStatus>;
129
+ readonly submitting: ReadonlySignal<boolean>;
130
+ /**
131
+ * Создать GroupNode только со схемой формы (обратная совместимость)
132
+ */
133
+ constructor(schema: FormSchema<T>);
134
+ /**
135
+ * Создать GroupNode с полной конфигурацией (form, behavior, validation)
136
+ */
137
+ constructor(config: GroupNodeConfig<T>);
138
+ getValue(): T;
139
+ setValue(value: T, options?: SetValueOptions): void;
140
+ patchValue(value: Partial<T>): void;
141
+ /**
142
+ * Сбросить форму к указанным значениям (или к initialValues)
143
+ *
144
+ * @param value - опциональный объект со значениями для сброса
145
+ *
146
+ * @remarks
147
+ * Рекурсивно вызывает reset() для всех полей формы
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * // Сброс к initialValues
152
+ * form.reset();
153
+ *
154
+ * // Сброс к новым значениям
155
+ * form.reset({ email: 'new@mail.com', password: '' });
156
+ * ```
157
+ */
158
+ reset(value?: T): void;
159
+ /**
160
+ * Сбросить форму к исходным значениям (initialValues)
161
+ *
162
+ * @remarks
163
+ * Рекурсивно вызывает resetToInitial() для всех полей формы.
164
+ * Более явный способ сброса к начальным значениям по сравнению с reset()
165
+ *
166
+ * Полезно когда:
167
+ * - Пользователь нажал "Cancel" - полная отмена изменений
168
+ * - Форма была изменена через reset(newValues), но нужно вернуться к самому началу
169
+ * - Явное намерение показать "отмена всех изменений"
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const form = new GroupNode({
174
+ * email: { value: 'initial@mail.com', component: Input },
175
+ * name: { value: 'John', component: Input }
176
+ * });
177
+ *
178
+ * form.email.setValue('changed@mail.com');
179
+ * form.reset({ email: 'temp@mail.com', name: 'Jane' });
180
+ * console.log(form.getValue()); // { email: 'temp@mail.com', name: 'Jane' }
181
+ *
182
+ * form.resetToInitial();
183
+ * console.log(form.getValue()); // { email: 'initial@mail.com', name: 'John' }
184
+ * ```
185
+ */
186
+ resetToInitial(): void;
187
+ validate(): Promise<boolean>;
188
+ /**
189
+ * Установить form-level validation errors
190
+ * Используется для server-side validation или кросс-полевых ошибок
191
+ *
192
+ * @param errors - массив ошибок уровня формы
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // Server-side validation после submit
197
+ * try {
198
+ * await api.createUser(form.getValue());
199
+ * } catch (error) {
200
+ * form.setErrors([
201
+ * { code: 'duplicate_email', message: 'Email уже используется' }
202
+ * ]);
203
+ * }
204
+ * ```
205
+ */
206
+ setErrors(errors: ValidationError[]): void;
207
+ /**
208
+ * Очистить все errors (form-level + field-level)
209
+ */
210
+ clearErrors(): void;
211
+ /**
212
+ * Получить поле по ключу
213
+ *
214
+ * Публичный метод для доступа к полю из fieldRegistry
215
+ *
216
+ * @param key - Ключ поля
217
+ * @returns FormNode или undefined, если поле не найдено
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const emailField = form.getField('email');
222
+ * if (emailField) {
223
+ * console.log(emailField.value.value);
224
+ * }
225
+ * ```
226
+ */
227
+ getField<K extends keyof T>(key: K): FormNode<T[K]> | undefined;
228
+ /**
229
+ * Получить Map всех полей формы
230
+ *
231
+ * Используется в FieldPathNavigator для навигации по полям
232
+ *
233
+ * @returns Map полей формы
234
+ */
235
+ get fields(): FieldRegistry<T>;
236
+ /**
237
+ * Получить Proxy-инстанс для прямого доступа к полям
238
+ *
239
+ * Proxy позволяет обращаться к полям формы напрямую через точечную нотацию:
240
+ * - form.email вместо form.fields.get('email')
241
+ * - form.address.city вместо form.fields.get('address').fields.get('city')
242
+ *
243
+ * Используется в:
244
+ * - BehaviorApplicator для доступа к полям в behavior functions
245
+ * - ValidationApplicator для доступа к форме в tree validators
246
+ *
247
+ * @returns Proxy-инстанс с типобезопасным доступом к полям или сама форма, если proxy не доступен
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * const form = new GroupNode({
252
+ * controls: {
253
+ * email: new FieldNode({ value: '' }),
254
+ * name: new FieldNode({ value: '' })
255
+ * }
256
+ * });
257
+ *
258
+ * const proxy = form.getProxy();
259
+ * console.log(proxy.email.value); // Прямой доступ к полю
260
+ * ```
261
+ */
262
+ getProxy(): GroupNodeWithControls<T>;
263
+ /**
264
+ * Получить все поля формы как итератор
265
+ *
266
+ * Предоставляет доступ к внутренним полям для валидации и других операций
267
+ *
268
+ * @returns Итератор по всем полям формы
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * // Валидация всех полей
273
+ * await Promise.all(
274
+ * Array.from(form.getAllFields()).map(field => field.validate())
275
+ * );
276
+ * ```
277
+ */
278
+ getAllFields(): IterableIterator<FormNode<FormValue>>;
279
+ /**
280
+ * Hook: вызывается после markAsTouched()
281
+ *
282
+ * Для GroupNode: рекурсивно помечаем все дочерние поля как touched
283
+ */
284
+ protected onMarkAsTouched(): void;
285
+ /**
286
+ * Hook: вызывается после markAsUntouched()
287
+ *
288
+ * Для GroupNode: рекурсивно помечаем все дочерние поля как untouched
289
+ */
290
+ protected onMarkAsUntouched(): void;
291
+ /**
292
+ * Hook: вызывается после markAsDirty()
293
+ *
294
+ * Для GroupNode: рекурсивно помечаем все дочерние поля как dirty
295
+ */
296
+ protected onMarkAsDirty(): void;
297
+ /**
298
+ * Hook: вызывается после markAsPristine()
299
+ *
300
+ * Для GroupNode: рекурсивно помечаем все дочерние поля как pristine
301
+ */
302
+ protected onMarkAsPristine(): void;
303
+ /**
304
+ * Отправить форму
305
+ * Валидирует форму и вызывает onSubmit если форма валидна
306
+ */
307
+ submit<R>(onSubmit: (values: T) => Promise<R> | R): Promise<R | null>;
308
+ /**
309
+ * Применить validation schema к форме
310
+ *
311
+ * Использует локальный реестр валидаторов (this.validationRegistry)
312
+ * вместо глобального Singleton для изоляции форм друг от друга.
313
+ */
314
+ applyValidationSchema(schemaFn: ValidationSchemaFn<T>): void;
315
+ /**
316
+ * Применить behavior schema к форме
317
+ *
318
+ * ✅ РЕФАКТОРИНГ: Делегирование BehaviorApplicator (SRP)
319
+ *
320
+ * Логика применения behavior схемы извлечена в BehaviorApplicator для:
321
+ * - Соблюдения Single Responsibility Principle
322
+ * - Уменьшения размера GroupNode (~50 строк)
323
+ * - Улучшения тестируемости
324
+ * - Консистентности с ValidationApplicator
325
+ *
326
+ * @param schemaFn Функция описания поведения формы
327
+ * @returns Функция cleanup для отписки от всех behaviors
328
+ *
329
+ * @example
330
+ * ```typescript
331
+ * import { copyFrom, enableWhen, computeFrom } from '@/lib/forms/core/behaviors';
332
+ *
333
+ * const behaviorSchema: BehaviorSchemaFn<MyForm> = (path) => {
334
+ * copyFrom(path.residenceAddress, path.registrationAddress, {
335
+ * when: (form) => form.sameAsRegistration === true
336
+ * });
337
+ *
338
+ * enableWhen(path.propertyValue, (form) => form.loanType === 'mortgage');
339
+ *
340
+ * computeFrom(
341
+ * path.initialPayment,
342
+ * [path.propertyValue],
343
+ * (propertyValue) => propertyValue ? propertyValue * 0.2 : null
344
+ * );
345
+ * };
346
+ *
347
+ * const cleanup = form.applyBehaviorSchema(behaviorSchema);
348
+ *
349
+ * // Cleanup при unmount
350
+ * useEffect(() => cleanup, []);
351
+ * ```
352
+ */
353
+ applyBehaviorSchema(schemaFn: BehaviorSchemaFn<T>): () => void;
354
+ /**
355
+ * Получить вложенное поле по пути
356
+ *
357
+ * Поддерживаемые форматы путей:
358
+ * - Simple: "email" - получить поле верхнего уровня
359
+ * - Nested: "address.city" - получить вложенное поле
360
+ * - Array index: "items[0]" - получить элемент массива по индексу
361
+ * - Combined: "items[0].name" - получить поле элемента массива
362
+ *
363
+ * @param path - Путь к полю
364
+ * @returns FormNode если найдено, undefined если путь не существует
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const form = new GroupNode({
369
+ * email: { value: '', component: Input },
370
+ * address: {
371
+ * city: { value: '', component: Input }
372
+ * },
373
+ * items: [{ name: { value: '', component: Input } }]
374
+ * });
375
+ *
376
+ * form.getFieldByPath('email'); // FieldNode
377
+ * form.getFieldByPath('address.city'); // FieldNode
378
+ * form.getFieldByPath('items[0]'); // GroupNode
379
+ * form.getFieldByPath('items[0].name'); // FieldNode
380
+ * form.getFieldByPath('invalid.path'); // undefined
381
+ * ```
382
+ */
383
+ getFieldByPath(path: string): FormNode<FormValue> | undefined;
384
+ /**
385
+ * Применить contextual валидаторы к полям
386
+ *
387
+ * ✅ РЕФАКТОРИНГ: Делегирование ValidationApplicator (SRP)
388
+ *
389
+ * Логика применения валидаторов извлечена в ValidationApplicator для:
390
+ * - Соблюдения Single Responsibility Principle
391
+ * - Уменьшения размера GroupNode (~120 строк)
392
+ * - Улучшения тестируемости
393
+ *
394
+ * @param validators Зарегистрированные валидаторы
395
+ */
396
+ applyContextualValidators(validators: ValidatorRegistration[]): Promise<void>;
397
+ /**
398
+ * Создать узел на основе конфигурации
399
+ *
400
+ * ✅ РЕФАКТОРИНГ: Полное делегирование NodeFactory
401
+ *
402
+ * NodeFactory теперь обрабатывает:
403
+ * - Массивы [schema, ...items]
404
+ * - FieldConfig
405
+ * - GroupConfig
406
+ * - ArrayConfig
407
+ *
408
+ * @param config Конфигурация узла
409
+ * @returns Созданный узел формы
410
+ * @private
411
+ */
412
+ private createNode;
413
+ /**
414
+ * Связывает два поля: при изменении source автоматически обновляется target
415
+ * Поддерживает опциональную трансформацию значения
416
+ *
417
+ * @param sourceKey - Ключ поля-источника
418
+ * @param targetKey - Ключ поля-цели
419
+ * @param transform - Опциональная функция трансформации значения
420
+ * @returns Функция отписки для cleanup
421
+ *
422
+ * @example
423
+ * ```typescript
424
+ * // Автоматический расчет минимального взноса от стоимости недвижимости
425
+ * const dispose = form.linkFields(
426
+ * 'propertyValue',
427
+ * 'initialPayment',
428
+ * (propertyValue) => propertyValue ? propertyValue * 0.2 : null
429
+ * );
430
+ *
431
+ * // При изменении propertyValue → автоматически обновится initialPayment
432
+ * form.propertyValue.setValue(1000000);
433
+ * // initialPayment станет 200000
434
+ *
435
+ * // Cleanup
436
+ * useEffect(() => dispose, []);
437
+ * ```
438
+ */
439
+ linkFields<K1 extends keyof T, K2 extends keyof T>(sourceKey: K1, targetKey: K2, transform?: (value: T[K1]) => T[K2]): () => void;
440
+ /**
441
+ * Подписка на изменения вложенного поля по строковому пути
442
+ * Поддерживает вложенные пути типа "address.city"
443
+ *
444
+ * @param fieldPath - Строковый путь к полю (например, "address.city")
445
+ * @param callback - Функция, вызываемая при изменении поля
446
+ * @returns Функция отписки для cleanup
447
+ *
448
+ * @example
449
+ * ```typescript
450
+ * // Подписка на изменение страны для загрузки городов
451
+ * const dispose = form.watchField(
452
+ * 'registrationAddress.country',
453
+ * async (countryCode) => {
454
+ * if (countryCode) {
455
+ * const cities = await fetchCitiesByCountry(countryCode);
456
+ * form.registrationAddress.city.updateComponentProps({
457
+ * options: cities
458
+ * });
459
+ * }
460
+ * }
461
+ * );
462
+ *
463
+ * // Cleanup
464
+ * useEffect(() => dispose, []);
465
+ * ```
466
+ */
467
+ watchField<K extends keyof T>(fieldPath: K extends string ? K : string, callback: (value: T[K]) => void | Promise<void>): () => void;
468
+ /**
469
+ * Hook: вызывается после disable()
470
+ *
471
+ * Для GroupNode: рекурсивно отключаем все дочерние поля
472
+ */
473
+ protected onDisable(): void;
474
+ /**
475
+ * Hook: вызывается после enable()
476
+ *
477
+ * Для GroupNode: рекурсивно включаем все дочерние поля
478
+ */
479
+ protected onEnable(): void;
480
+ /**
481
+ * Очистить все ресурсы узла
482
+ * Рекурсивно очищает все subscriptions и дочерние узлы
483
+ *
484
+ * @example
485
+ * ```typescript
486
+ * useEffect(() => {
487
+ * return () => {
488
+ * form.dispose();
489
+ * };
490
+ * }, []);
491
+ * ```
492
+ */
493
+ dispose(): void;
494
+ }