@reformer/core 10.2.0 → 11.0.0-beta.10

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 (285) hide show
  1. package/README.md +90 -68
  2. package/dist/behaviors-value-D05z3my6.js +109 -0
  3. package/dist/behaviors.d.ts +1 -1
  4. package/dist/behaviors.js +376 -211
  5. package/dist/create-model-DPSG3I0O.js +30 -0
  6. package/dist/date-utils-90-qZbse.js +43 -0
  7. package/dist/en-HP8XEych.js +44 -0
  8. package/dist/form/aggregate-signals.d.ts +21 -63
  9. package/dist/form/behaviors/collections.d.ts +84 -0
  10. package/dist/form/behaviors/context.d.ts +56 -0
  11. package/dist/form/behaviors/index.d.ts +30 -0
  12. package/dist/form/behaviors/internals.d.ts +41 -0
  13. package/dist/form/{behaviors-node.d.ts → behaviors/node.d.ts} +28 -5
  14. package/dist/form/behaviors/operators.d.ts +59 -0
  15. package/dist/form/behaviors/schema-operators.d.ts +83 -0
  16. package/dist/form/behaviors/types.d.ts +37 -0
  17. package/dist/form/create-form.d.ts +59 -70
  18. package/dist/form/flow/flow.d.ts +87 -0
  19. package/dist/form/form-bundle.d.ts +153 -0
  20. package/dist/form/form-level.d.ts +121 -0
  21. package/dist/form/form-proxy-builder.d.ts +6 -22
  22. package/dist/form/index.d.ts +23 -27
  23. package/dist/form/nodes/form-array-node.d.ts +100 -0
  24. package/dist/form/nodes/form-control-node.d.ts +73 -0
  25. package/dist/form/nodes/form-group-node.d.ts +66 -0
  26. package/dist/form/nodes/node-kind.d.ts +29 -0
  27. package/dist/form/nodes/state/availability.d.ts +6 -0
  28. package/dist/form/nodes/state/component.d.ts +6 -0
  29. package/dist/form/nodes/state/index.d.ts +12 -0
  30. package/dist/form/nodes/state/interaction.d.ts +13 -0
  31. package/dist/form/nodes/state/issues.d.ts +9 -0
  32. package/dist/form/nodes/state/pending.d.ts +6 -0
  33. package/dist/form/schema/compile.d.ts +59 -0
  34. package/dist/form/schema/compiled.d.ts +143 -0
  35. package/dist/form/schema/row-key.d.ts +11 -0
  36. package/dist/form/schema-controller.d.ts +159 -0
  37. package/dist/form/schema-subtree.d.ts +28 -0
  38. package/dist/form/signal-node-registry.d.ts +27 -22
  39. package/dist/form/submission.d.ts +93 -0
  40. package/dist/form/type-guards.d.ts +14 -73
  41. package/dist/form/types/contracts.d.ts +21 -91
  42. package/dist/form/types/field-config.d.ts +27 -0
  43. package/dist/form/types/index.d.ts +5 -91
  44. package/dist/form/types/nodes.d.ts +159 -0
  45. package/dist/form/types/schema-node.d.ts +148 -50
  46. package/dist/form/types/validation-schema.d.ts +24 -41
  47. package/dist/form/validation/context.d.ts +67 -0
  48. package/dist/form/validation/index.d.ts +24 -28
  49. package/dist/form/validation/operators.d.ts +101 -0
  50. package/dist/form/validation/run.d.ts +120 -0
  51. package/dist/form/validation/strategy.d.ts +89 -0
  52. package/dist/form/validation/types.d.ts +83 -0
  53. package/dist/form/validators/date-utils.d.ts +42 -0
  54. package/dist/form/validators/email.d.ts +23 -0
  55. package/dist/form/{validation/validators → validators}/file-type.d.ts +10 -10
  56. package/dist/form/{validation/validators → validators}/file-utils.d.ts +3 -2
  57. package/dist/form/validators/future-date.d.ts +23 -0
  58. package/dist/form/{validation/validators → validators}/index.d.ts +7 -4
  59. package/dist/form/validators/integer.d.ts +22 -0
  60. package/dist/form/validators/is-date.d.ts +24 -0
  61. package/dist/form/validators/is-number.d.ts +25 -0
  62. package/dist/form/validators/max-age.d.ts +28 -0
  63. package/dist/form/validators/max-date.d.ts +25 -0
  64. package/dist/form/{validation/validators → validators}/max-file-size.d.ts +10 -10
  65. package/dist/form/validators/max-files.d.ts +26 -0
  66. package/dist/form/validators/max-length.d.ts +33 -0
  67. package/dist/form/validators/max-total-file-size.d.ts +26 -0
  68. package/dist/form/validators/max.d.ts +26 -0
  69. package/dist/form/validators/min-age.d.ts +27 -0
  70. package/dist/form/validators/min-date.d.ts +25 -0
  71. package/dist/form/{validation/validators → validators}/min-file-size.d.ts +10 -10
  72. package/dist/form/validators/min-files.d.ts +27 -0
  73. package/dist/form/validators/min-length.d.ts +33 -0
  74. package/dist/form/validators/min.d.ts +26 -0
  75. package/dist/form/validators/multiple-of.d.ts +25 -0
  76. package/dist/form/validators/non-negative.d.ts +22 -0
  77. package/dist/form/validators/non-zero.d.ts +22 -0
  78. package/dist/form/validators/past-date.d.ts +23 -0
  79. package/dist/form/validators/pattern.d.ts +26 -0
  80. package/dist/form/{validation/validators → validators}/phone.d.ts +11 -11
  81. package/dist/form/validators/required.d.ts +29 -0
  82. package/dist/form/validators/url.d.ts +45 -0
  83. package/dist/form/validators/validation-issue.d.ts +8 -0
  84. package/dist/i18n/descriptor.d.ts +54 -0
  85. package/dist/i18n/en.json.d.ts +49 -0
  86. package/dist/i18n/loader.d.ts +71 -0
  87. package/dist/i18n/locale-store.d.ts +46 -0
  88. package/dist/i18n/locale.d.ts +90 -0
  89. package/dist/i18n/message-format.d.ts +136 -0
  90. package/dist/i18n/resolve-localized.d.ts +17 -0
  91. package/dist/i18n/ru.json.d.ts +49 -0
  92. package/dist/i18n/translator.d.ts +61 -0
  93. package/dist/i18n/validation-message.d.ts +53 -0
  94. package/dist/i18n.d.ts +26 -0
  95. package/dist/i18n.js +86 -0
  96. package/dist/index.d.ts +18 -6
  97. package/dist/index.js +932 -2779
  98. package/dist/loader-BWkigpVe.js +52 -0
  99. package/dist/locale/en.d.ts +2 -0
  100. package/dist/locale/en.js +5 -0
  101. package/dist/locale/en.json +45 -0
  102. package/dist/locale/index.d.ts +18 -0
  103. package/dist/locale/ru.d.ts +2 -0
  104. package/dist/locale/ru.js +44 -0
  105. package/dist/locale/ru.json +45 -0
  106. package/dist/locale-CG54AU2Q.js +219 -0
  107. package/dist/locale.d.ts +2 -0
  108. package/dist/locale.js +9 -0
  109. package/dist/{state → model}/behaviors-value.d.ts +24 -6
  110. package/dist/{state/form-model.d.ts → model/create-model.d.ts} +18 -4
  111. package/dist/{state → model}/derived-registry.d.ts +1 -1
  112. package/dist/model/index.d.ts +42 -0
  113. package/dist/model/model-nodes.d.ts +190 -0
  114. package/dist/model/model-signals-proxy.d.ts +63 -0
  115. package/dist/model/model-value-proxy.d.ts +84 -0
  116. package/dist/{state → model}/safe-effect.d.ts +50 -2
  117. package/dist/model/types.d.ts +239 -0
  118. package/dist/model.d.ts +2 -0
  119. package/dist/model.js +27 -0
  120. package/dist/node-kind-C-r6ZMdo.js +15 -0
  121. package/dist/platforms/react/field-binding/field-adapter.d.ts +87 -0
  122. package/dist/platforms/react/field-binding/field-handle.d.ts +53 -0
  123. package/dist/platforms/react/form-bundle-context.d.ts +27 -0
  124. package/dist/{form → platforms/react}/hooks/types.d.ts +60 -38
  125. package/dist/platforms/react/hooks/use-form-bundle.d.ts +41 -0
  126. package/dist/platforms/react/hooks/use-form-flow.d.ts +40 -0
  127. package/dist/{form → platforms/react}/hooks/use-form-validation.d.ts +13 -7
  128. package/dist/{form → platforms/react}/hooks/useArrayLength.d.ts +6 -6
  129. package/dist/{form → platforms/react}/hooks/useFormControl.d.ts +7 -9
  130. package/dist/{form → platforms/react}/hooks/useFormControlValue.d.ts +18 -18
  131. package/dist/{form → platforms/react}/hooks/useSignalSubscription.d.ts +9 -1
  132. package/dist/platforms/react/i18n/context.d.ts +18 -0
  133. package/dist/platforms/react/i18n/hooks.d.ts +65 -0
  134. package/dist/platforms/react/i18n/provider.d.ts +59 -0
  135. package/dist/platforms/react/index.d.ts +30 -0
  136. package/dist/react.d.ts +22 -0
  137. package/dist/react.js +505 -0
  138. package/dist/runtime-token.d.ts +22 -0
  139. package/dist/safe-effect-BazLOv1g.js +669 -0
  140. package/dist/schema-controller-CpiO2JoK.js +143 -0
  141. package/dist/signals.d.ts +15 -9
  142. package/dist/signals.js +11 -6
  143. package/dist/strategy-DzvnsWLh.js +375 -0
  144. package/dist/type-guards-D-N_5Ddh.js +19 -0
  145. package/dist/validation-issue-B9mjI8jz.js +7 -0
  146. package/dist/validation-message-Ced9MGxs.js +194 -0
  147. package/dist/validation.d.ts +1 -1
  148. package/dist/validation.js +11 -165
  149. package/dist/validators/email.d.ts +1 -1
  150. package/dist/validators/email.js +5 -8
  151. package/dist/validators/future-date.d.ts +1 -1
  152. package/dist/validators/future-date.js +10 -13
  153. package/dist/validators/integer.d.ts +1 -1
  154. package/dist/validators/integer.js +4 -7
  155. package/dist/validators/is-date.d.ts +1 -1
  156. package/dist/validators/is-date.js +5 -8
  157. package/dist/validators/is-number.d.ts +1 -1
  158. package/dist/validators/is-number.js +4 -7
  159. package/dist/validators/max-age.d.ts +1 -1
  160. package/dist/validators/max-age.js +8 -12
  161. package/dist/validators/max-date.d.ts +1 -1
  162. package/dist/validators/max-date.js +10 -13
  163. package/dist/validators/max-length.d.ts +1 -1
  164. package/dist/validators/max-length.js +7 -10
  165. package/dist/validators/max.d.ts +1 -1
  166. package/dist/validators/max.js +4 -7
  167. package/dist/validators/min-age.d.ts +1 -1
  168. package/dist/validators/min-age.js +10 -11
  169. package/dist/validators/min-date.d.ts +1 -1
  170. package/dist/validators/min-date.js +8 -11
  171. package/dist/validators/min-length.d.ts +1 -1
  172. package/dist/validators/min-length.js +4 -7
  173. package/dist/validators/min.d.ts +1 -1
  174. package/dist/validators/min.js +4 -7
  175. package/dist/validators/multiple-of.d.ts +1 -1
  176. package/dist/validators/multiple-of.js +11 -10
  177. package/dist/validators/non-negative.d.ts +1 -1
  178. package/dist/validators/non-negative.js +2 -5
  179. package/dist/validators/non-zero.d.ts +1 -1
  180. package/dist/validators/non-zero.js +4 -7
  181. package/dist/validators/past-date.d.ts +1 -1
  182. package/dist/validators/past-date.js +10 -13
  183. package/dist/validators/pattern.d.ts +1 -1
  184. package/dist/validators/pattern.js +5 -8
  185. package/dist/validators/phone.d.ts +1 -1
  186. package/dist/validators/phone.js +10 -11
  187. package/dist/validators/required.d.ts +1 -1
  188. package/dist/validators/required.js +4 -7
  189. package/dist/validators/url.d.ts +1 -1
  190. package/dist/validators/url.js +48 -17
  191. package/dist/validators.d.ts +1 -5
  192. package/dist/validators.js +98 -154
  193. package/docs/llms/01-api-reference.md +89 -0
  194. package/docs/llms/02-quick-start.md +181 -0
  195. package/docs/llms/03-api-signatures.md +494 -0
  196. package/docs/llms/04-common-patterns.md +204 -0
  197. package/docs/llms/05-common-mistakes.md +192 -0
  198. package/docs/llms/06-troubleshooting.md +16 -0
  199. package/docs/llms/07-complete-import.md +130 -0
  200. package/docs/llms/08-form-types.md +54 -0
  201. package/docs/llms/09-formschema.md +191 -0
  202. package/docs/llms/10-arrays.md +241 -0
  203. package/docs/llms/11-async-watchfield.md +53 -0
  204. package/docs/llms/12-array-cleanup.md +31 -0
  205. package/docs/llms/13-multi-step.md +162 -0
  206. package/docs/llms/14-extended-mistakes.md +101 -0
  207. package/docs/llms/15-project-structure.md +279 -0
  208. package/docs/llms/16-ui-components.md +229 -0
  209. package/docs/llms/17-nonexistent-api.md +278 -0
  210. package/docs/llms/18-conditional-fields.md +222 -0
  211. package/docs/llms/19-reading-values.md +100 -0
  212. package/docs/llms/20-compute-vs-watch.md +153 -0
  213. package/docs/llms/21-array-operations.md +163 -0
  214. package/docs/llms/22-cycle-detection.md +86 -0
  215. package/docs/llms/23-copy-from.md +141 -0
  216. package/docs/llms/24-sync-fields.md +115 -0
  217. package/docs/llms/25-reset-when.md +122 -0
  218. package/docs/llms/26-transform-value.md +136 -0
  219. package/docs/llms/27-revalidate-when.md +133 -0
  220. package/docs/llms/28-submit-and-reset.md +409 -0
  221. package/docs/llms/29-async-preload.md +203 -0
  222. package/docs/llms/30-type-safety-recipes.md +213 -0
  223. package/docs/llms/31-async-validator-debounce.md +178 -0
  224. package/docs/llms/32-async-options-loading.md +108 -0
  225. package/docs/llms/33-validation-strategy.md +305 -0
  226. package/docs/llms/34-i18n.md +298 -0
  227. package/docs/llms/35-unified-contract.md +309 -0
  228. package/docs/llms/36-issue-messages.md +284 -0
  229. package/docs/llms/37-compiled-schema.md +332 -0
  230. package/docs/llms/38-form-flow.md +396 -0
  231. package/llms-index.json +1 -0
  232. package/llms.txt +10014 -3826
  233. package/package.json +77 -15
  234. package/dist/behaviors-node-DGEFMTQu.js +0 -18
  235. package/dist/behaviors-value-C7dSEhCc.js +0 -134
  236. package/dist/date-utils-dTT_x_Be.js +0 -31
  237. package/dist/derived-registry-CluZCQ7U.js +0 -16
  238. package/dist/form/behaviors.d.ts +0 -133
  239. package/dist/form/error-handler.d.ts +0 -166
  240. package/dist/form/factories/index.d.ts +0 -6
  241. package/dist/form/factories/node-factory.d.ts +0 -188
  242. package/dist/form/form-submitter.d.ts +0 -125
  243. package/dist/form/nodes/array-node.d.ts +0 -360
  244. package/dist/form/nodes/field-node.d.ts +0 -294
  245. package/dist/form/nodes/form-node.d.ts +0 -340
  246. package/dist/form/nodes/group-node.d.ts +0 -288
  247. package/dist/form/nodes/model-array-node.d.ts +0 -121
  248. package/dist/form/status-machine.d.ts +0 -153
  249. package/dist/form/types/deep-schema.d.ts +0 -116
  250. package/dist/form/types/form-proxy.d.ts +0 -141
  251. package/dist/form/unique-id.d.ts +0 -53
  252. package/dist/form/validation/validators/date-utils.d.ts +0 -30
  253. package/dist/form/validation/validators/email.d.ts +0 -23
  254. package/dist/form/validation/validators/future-date.d.ts +0 -23
  255. package/dist/form/validation/validators/integer.d.ts +0 -22
  256. package/dist/form/validation/validators/is-date.d.ts +0 -23
  257. package/dist/form/validation/validators/is-number.d.ts +0 -24
  258. package/dist/form/validation/validators/max-age.d.ts +0 -25
  259. package/dist/form/validation/validators/max-date.d.ts +0 -25
  260. package/dist/form/validation/validators/max-files.d.ts +0 -26
  261. package/dist/form/validation/validators/max-length.d.ts +0 -27
  262. package/dist/form/validation/validators/max-total-file-size.d.ts +0 -26
  263. package/dist/form/validation/validators/max.d.ts +0 -25
  264. package/dist/form/validation/validators/min-age.d.ts +0 -25
  265. package/dist/form/validation/validators/min-date.d.ts +0 -25
  266. package/dist/form/validation/validators/min-files.d.ts +0 -26
  267. package/dist/form/validation/validators/min-length.d.ts +0 -27
  268. package/dist/form/validation/validators/min.d.ts +0 -25
  269. package/dist/form/validation/validators/multiple-of.d.ts +0 -24
  270. package/dist/form/validation/validators/non-negative.d.ts +0 -22
  271. package/dist/form/validation/validators/non-zero.d.ts +0 -22
  272. package/dist/form/validation/validators/past-date.d.ts +0 -23
  273. package/dist/form/validation/validators/pattern.d.ts +0 -33
  274. package/dist/form/validation/validators/required.d.ts +0 -32
  275. package/dist/form/validation/validators/url.d.ts +0 -43
  276. package/dist/form/validation-schema.d.ts +0 -106
  277. package/dist/form/validation-strategy.d.ts +0 -55
  278. package/dist/form/validators.d.ts +0 -6
  279. package/dist/form-model-DYCzGGKF.js +0 -286
  280. package/dist/state/index.d.ts +0 -31
  281. package/dist/state/subscription-manager.d.ts +0 -180
  282. package/dist/state/types.d.ts +0 -144
  283. package/dist/state.d.ts +0 -2
  284. package/dist/state.js +0 -21
  285. package/dist/subscription-manager-705bls97.js +0 -171
@@ -1,188 +0,0 @@
1
- import { FormNode } from '../nodes/form-node';
2
- import { ConfigWithSchema, ConfigWithValue, UnknownRecord } from '../types/index';
3
- /**
4
- * Фабрика для создания узлов формы.
5
- *
6
- * Определяет тип конфига и создаёт соответствующий узел (FieldNode, GroupNode, ArrayNode).
7
- * Используется внутри `getReformerForm`/`group`/`array` — явно вызывать обычно не нужно.
8
- *
9
- * @example
10
- * ```typescript
11
- * import { NodeFactory } from '@reformer/core';
12
- *
13
- * const factory = new NodeFactory();
14
- * const node = factory.createNode({ value: '', component: Input }); // → FieldNode<string>
15
- * ```
16
- */
17
- export declare class NodeFactory {
18
- /**
19
- * Создает узел формы на основе конфигурации
20
- *
21
- * ✅ ОБНОВЛЕНО: Теперь поддерживает массивы напрямую
22
- *
23
- * Автоматически определяет тип узла:
24
- * - FieldNode: имеет value и component
25
- * - ArrayNode: массив [schema, ...items] или { schema, initialItems }
26
- * - GroupNode: объект без value, component, schema
27
- *
28
- * @param config Конфигурация узла
29
- * @returns Экземпляр FieldNode, GroupNode или ArrayNode
30
- * @throws Error если конфиг не соответствует ни одному типу
31
- *
32
- * @example
33
- * ```typescript
34
- * const factory = new NodeFactory();
35
- *
36
- * // FieldNode
37
- * const field = factory.createNode({
38
- * value: 'test@mail.com',
39
- * component: Input,
40
- * validators: [required, email]
41
- * });
42
- *
43
- * // GroupNode
44
- * const group = factory.createNode({
45
- * email: { value: '', component: Input },
46
- * password: { value: '', component: Input }
47
- * });
48
- *
49
- * // ArrayNode (объект)
50
- * const array = factory.createNode({
51
- * schema: { title: { value: '', component: Input } },
52
- * initialItems: [{ title: 'Item 1' }]
53
- * });
54
- *
55
- * // ArrayNode (массив) - новый формат
56
- * const array2 = factory.createNode([
57
- * { title: { value: '', component: Input } }, // schema
58
- * { title: 'Item 1' }, // initial item 1
59
- * { title: 'Item 2' } // initial item 2
60
- * ]);
61
- * ```
62
- */
63
- createNode(config: unknown): FormNode<unknown>;
64
- /**
65
- * Создать ArrayNode из массива [schema, ...initialItems]
66
- *
67
- * ✅ НОВОЕ: Извлечено из GroupNode для централизации логики
68
- *
69
- * Формат: [itemSchema, ...initialItems]
70
- * - Первый элемент - схема элемента массива
71
- * - Остальные элементы - начальные значения
72
- *
73
- * @param config Массив с схемой и начальными элементами
74
- * @returns ArrayNode
75
- *
76
- * @example
77
- * ```typescript
78
- * const factory = new NodeFactory();
79
- *
80
- * // Массив с начальными элементами
81
- * const array = factory.createArrayNodeFromArray([
82
- * { title: { value: '', component: Input } }, // schema
83
- * { title: 'Item 1' }, // initial value
84
- * { title: 'Item 2' } // initial value
85
- * ]);
86
- * ```
87
- * @private
88
- */
89
- private createArrayNodeFromArray;
90
- /**
91
- * Извлечь значения из схемы (рекурсивно)
92
- *
93
- * ✅ НОВОЕ: Извлечено из GroupNode для централизации логики
94
- *
95
- * Преобразует схему формы в объект со значениями:
96
- * - `{ name: { value: 'John', component: Input } } → { name: 'John' }`
97
- * - Поддерживает вложенные группы
98
- * - Поддерживает массивы
99
- *
100
- * @param schema Схема формы
101
- * @returns Объект со значениями полей
102
- *
103
- * @example
104
- * ```typescript
105
- * const factory = new NodeFactory();
106
- *
107
- * const schema = {
108
- * name: { value: 'John', component: Input },
109
- * age: { value: 30, component: Input },
110
- * address: {
111
- * city: { value: 'Moscow', component: Input }
112
- * }
113
- * };
114
- *
115
- * factory.extractValues(schema);
116
- * // { name: 'John', age: 30, address: { city: 'Moscow' } }
117
- * ```
118
- */
119
- extractValues(schema: unknown): unknown;
120
- /**
121
- * Проверяет, является ли конфиг конфигурацией поля (FieldConfig)
122
- *
123
- * FieldConfig имеет обязательные свойства:
124
- * - value: начальное значение поля
125
- * - component: React-компонент для отображения
126
- *
127
- * @param config Проверяемая конфигурация
128
- * @returns true если config является FieldConfig
129
- *
130
- * @example
131
- * ```typescript
132
- * const factory = new NodeFactory();
133
- *
134
- * factory.isFieldConfig({ value: '', component: Input }); // true
135
- * factory.isFieldConfig({ email: { value: '' } }); // false
136
- * factory.isFieldConfig(null); // false
137
- * ```
138
- */
139
- isFieldConfig(config: unknown): config is ConfigWithValue;
140
- /**
141
- * Проверяет, является ли конфиг конфигурацией массива (ArrayConfig)
142
- *
143
- * ArrayConfig имеет обязательное свойство:
144
- * - schema: схема для элементов массива
145
- *
146
- * И НЕ имеет:
147
- * - value (отличие от FieldConfig)
148
- *
149
- * @param config Проверяемая конфигурация
150
- * @returns true если config является ArrayConfig
151
- *
152
- * @example
153
- * ```typescript
154
- * const factory = new NodeFactory();
155
- *
156
- * factory.isArrayConfig({ schema: {}, initialItems: [] }); // true
157
- * factory.isArrayConfig({ value: '', component: Input }); // false
158
- * factory.isArrayConfig({ email: { value: '' } }); // false
159
- * ```
160
- */
161
- isArrayConfig(config: unknown): config is ConfigWithSchema;
162
- /**
163
- * Проверяет, является ли конфиг конфигурацией группы (GroupConfig)
164
- *
165
- * GroupConfig - это объект, который:
166
- * - НЕ является FieldConfig (нет value/component)
167
- * - НЕ является ArrayConfig (нет schema)
168
- * - Содержит вложенные конфиги полей/групп/массивов
169
- *
170
- * @param config Проверяемая конфигурация
171
- * @returns true если config является GroupConfig
172
- *
173
- * @example
174
- * ```typescript
175
- * const factory = new NodeFactory();
176
- *
177
- * factory.isGroupConfig({
178
- * email: { value: '', component: Input },
179
- * password: { value: '', component: Input }
180
- * }); // true
181
- *
182
- * factory.isGroupConfig({ value: '', component: Input }); // false
183
- * factory.isGroupConfig({ schema: {} }); // false
184
- * factory.isGroupConfig(null); // false
185
- * ```
186
- */
187
- isGroupConfig(config: unknown): config is UnknownRecord;
188
- }
@@ -1,125 +0,0 @@
1
- import { ReadonlySignal } from '@preact/signals-core';
2
- /**
3
- * Интерфейс формы для FormSubmitter
4
- * Минимальный контракт для работы с любой формой
5
- */
6
- export interface SubmittableForm<T extends object> {
7
- /** Пометить все поля как touched */
8
- markAsTouched(): void;
9
- /** Валидировать форму */
10
- validate(): Promise<boolean>;
11
- /** Получить значения формы */
12
- getValue(): T;
13
- }
14
- /**
15
- * Опции для submit
16
- */
17
- export interface SubmitOptions {
18
- /** Пропустить валидацию перед submit */
19
- skipValidation?: boolean;
20
- /** Пропустить markAsTouched перед submit */
21
- skipTouch?: boolean;
22
- }
23
- /**
24
- * Результат submit
25
- */
26
- export interface SubmitResult<R> {
27
- /** Успешно ли выполнен submit */
28
- success: boolean;
29
- /** Результат от onSubmit callback */
30
- data: R | null;
31
- /** Ошибка, если submit не удался */
32
- error?: Error;
33
- }
34
- /**
35
- * FormSubmitter - управляет процессом отправки формы
36
- *
37
- * @example
38
- * ```typescript
39
- * const submitter = new FormSubmitter(form);
40
- *
41
- * // Простой submit
42
- * const result = await submitter.submit(async (values) => {
43
- * return await api.saveForm(values);
44
- * });
45
- *
46
- * // Проверка состояния
47
- * if (submitter.submitting.value) {
48
- * console.log('Форма отправляется...');
49
- * }
50
- * ```
51
- */
52
- export declare class FormSubmitter<T extends object> {
53
- private readonly form;
54
- /** Внутренний сигнал состояния отправки */
55
- private readonly _submitting;
56
- /** Публичный read-only сигнал состояния отправки */
57
- readonly submitting: ReadonlySignal<boolean>;
58
- /**
59
- * @param form - Форма для отправки
60
- */
61
- constructor(form: SubmittableForm<T>);
62
- /**
63
- * Отправить форму
64
- *
65
- * Процесс:
66
- * 1. Помечает все поля как touched (для отображения ошибок)
67
- * 2. Валидирует форму
68
- * 3. Если валидация успешна - вызывает onSubmit
69
- * 4. Управляет состоянием submitting
70
- *
71
- * @param onSubmit - Callback для отправки данных
72
- * @param options - Опции submit
73
- * @returns Результат от onSubmit или `null` если валидация не пройдена
74
- *
75
- * @remarks
76
- * Возвращаемый `null` неоднозначен: он сигналит и провал валидации, и легитимный `null`,
77
- * который вернул `onSubmit` (или void-обработчик). Чтобы различать эти случаи, используйте
78
- * {@link submitWithResult} — он отдаёт явный флаг `success`.
79
- *
80
- * @example
81
- * ```typescript
82
- * const result = await submitter.submit(async (values) => {
83
- * const response = await fetch('/api/form', {
84
- * method: 'POST',
85
- * body: JSON.stringify(values)
86
- * });
87
- * return response.json();
88
- * });
89
- *
90
- * if (result === null) {
91
- * console.log('Форма не прошла валидацию');
92
- * }
93
- * ```
94
- */
95
- submit<R>(onSubmit: (values: T) => Promise<R> | R, options?: SubmitOptions): Promise<R | null>;
96
- /**
97
- * Отправить форму с расширенным результатом
98
- *
99
- * В отличие от submit(), возвращает объект с информацией об успехе/ошибке
100
- *
101
- * @param onSubmit - Callback для отправки данных
102
- * @param options - Опции submit
103
- * @returns Объект SubmitResult с данными и статусом
104
- *
105
- * @example
106
- * ```typescript
107
- * const result = await submitter.submitWithResult(async (values) => {
108
- * return await api.saveForm(values);
109
- * });
110
- *
111
- * if (result.success) {
112
- * console.log('Сохранено:', result.data);
113
- * } else if (result.error) {
114
- * console.error('Ошибка:', result.error.message);
115
- * } else {
116
- * console.log('Валидация не пройдена');
117
- * }
118
- * ```
119
- */
120
- submitWithResult<R>(onSubmit: (values: T) => Promise<R> | R, options?: SubmitOptions): Promise<SubmitResult<R>>;
121
- /**
122
- * Проверить, идет ли отправка формы
123
- */
124
- isSubmitting(): boolean;
125
- }
@@ -1,360 +0,0 @@
1
- import { ReadonlySignal } from '@preact/signals-core';
2
- import { FormNode, SetValueOptions } from './form-node';
3
- import { FieldStatus, ValidationError } from '../types/index';
4
- import { FormSchema } from '../types/deep-schema';
5
- import { FormProxy } from '../types/form-proxy';
6
- /**
7
- * ArrayNode - массив форм с реактивным состоянием
8
- *
9
- * @group Nodes
10
- *
11
- * @example
12
- * ```typescript
13
- * const array = new ArrayNode({
14
- * title: { value: '', component: Input },
15
- * price: { value: 0, component: Input },
16
- * });
17
- *
18
- * array.push({ title: 'Item 1', price: 100 });
19
- * array.at(0)?.title.setValue('Updated');
20
- * console.log(array.length.value); // 1
21
- * ```
22
- */
23
- export declare class ArrayNode<T extends object> extends FormNode<T[]> {
24
- private items;
25
- private itemSchema;
26
- private initialItems;
27
- /**
28
- * Менеджер подписок для централизованного cleanup
29
- * Использует SubscriptionManager вместо массива для управления подписками
30
- */
31
- private disposers;
32
- /** Array-level validation errors (e.g., "минимум 1 элемент") */
33
- private readonly _arrayErrors;
34
- private validationSchemaFn?;
35
- private behaviorSchemaFn?;
36
- readonly value: ReadonlySignal<T[]>;
37
- readonly valid: ReadonlySignal<boolean>;
38
- readonly invalid: ReadonlySignal<boolean>;
39
- readonly touched: ReadonlySignal<boolean>;
40
- readonly dirty: ReadonlySignal<boolean>;
41
- readonly pending: ReadonlySignal<boolean>;
42
- readonly errors: ReadonlySignal<ValidationError[]>;
43
- readonly status: ReadonlySignal<FieldStatus>;
44
- readonly length: ReadonlySignal<number>;
45
- constructor(schema: FormSchema<T>, initialItems?: Partial<T>[]);
46
- /**
47
- * Добавить элемент в конец массива
48
- * @param initialValue - Начальные значения для нового элемента
49
- */
50
- push(initialValue?: Partial<T>): void;
51
- /**
52
- * Удалить элемент по индексу
53
- * @param index - Индекс элемента для удаления
54
- *
55
- * @remarks
56
- * Вызывает dispose() на удаляемом элементе для очистки подписок
57
- */
58
- removeAt(index: number): void;
59
- /**
60
- * Вставить элемент в массив
61
- * @param index - Индекс для вставки
62
- * @param initialValue - Начальные значения для нового элемента
63
- */
64
- insert(index: number, initialValue?: Partial<T>): void;
65
- /**
66
- * Переместить элемент массива с позиции `from` на позицию `to`
67
- *
68
- * @param from - Индекс перемещаемого элемента
69
- * @param to - Целевой индекс
70
- *
71
- * @remarks
72
- * Реордер не уничтожает элемент (dispose НЕ вызывается) — тот же инстанс под-формы
73
- * переезжает на новую позицию, состояние/валидация сохраняются. Длина не меняется.
74
- *
75
- * @example
76
- * ```typescript
77
- * // Поднять элемент #2 на одну позицию вверх
78
- * form.items.move(2, 1);
79
- * ```
80
- */
81
- move(from: number, to: number): void;
82
- /**
83
- * Поменять местами два элемента массива
84
- *
85
- * @param a - Индекс первого элемента
86
- * @param b - Индекс второго элемента
87
- *
88
- * @remarks
89
- * Как и {@link move}, не уничтожает элементы — меняет только их порядок.
90
- *
91
- * @example
92
- * ```typescript
93
- * form.items.swap(0, 2);
94
- * ```
95
- */
96
- swap(a: number, b: number): void;
97
- /**
98
- * Удалить все элементы массива
99
- *
100
- * @remarks
101
- * Вызывает dispose() на всех элементах для очистки подписок
102
- */
103
- clear(): void;
104
- /**
105
- * Получить элемент по индексу
106
- * @param index - Индекс элемента
107
- * @returns Типизированный GroupNode proxy или undefined если индекс вне границ
108
- */
109
- at(index: number): FormProxy<T> | undefined;
110
- getValue(): T[];
111
- setValue(values: T[], options?: SetValueOptions): void;
112
- patchValue(values: (T | undefined)[]): void;
113
- /**
114
- * Сбросить массив к указанным значениям (или очистить)
115
- *
116
- * @param values - опциональный массив значений для сброса
117
- *
118
- * @remarks
119
- * Очищает текущий массив и заполняет новыми элементами
120
- *
121
- * @example
122
- * ```typescript
123
- * // Очистить массив
124
- * arrayNode.reset();
125
- *
126
- * // Сбросить к новым значениям
127
- * arrayNode.reset([{ name: 'Item 1' }, { name: 'Item 2' }]);
128
- * ```
129
- */
130
- reset(values?: T[]): void;
131
- /**
132
- * Сбросить массив к исходным значениям (initialItems)
133
- *
134
- * @remarks
135
- * Восстанавливает массив в состояние, которое было при создании ArrayNode.
136
- * Более явный способ сброса к начальным значениям по сравнению с reset()
137
- *
138
- * Полезно когда:
139
- * - Пользователь нажал "Cancel" - вернуть массив к исходным элементам
140
- * - Массив был изменен через reset(newValues), но нужно вернуться к началу
141
- * - Явное намерение показать "отмена всех изменений"
142
- *
143
- * @example
144
- * ```typescript
145
- * const arrayNode = new ArrayNode(
146
- * { name: { value: '', component: Input } },
147
- * [{ name: 'Initial 1' }, { name: 'Initial 2' }]
148
- * );
149
- *
150
- * arrayNode.push({ name: 'New Item' });
151
- * arrayNode.reset([{ name: 'Temp' }]);
152
- * console.log(arrayNode.length.value); // 1
153
- *
154
- * arrayNode.resetToInitial();
155
- * console.log(arrayNode.length.value); // 2
156
- * console.log(arrayNode.at(0)?.name.value.value); // 'Initial 1'
157
- * ```
158
- */
159
- resetToInitial(): void;
160
- validate(): Promise<boolean>;
161
- /**
162
- * Установить array-level validation errors
163
- *
164
- * @param errors - Массив ошибок валидации уровня массива
165
- *
166
- * @example
167
- * ```typescript
168
- * arrayNode.setErrors([{
169
- * code: 'minItems',
170
- * message: 'Минимум 1 элемент обязателен',
171
- * }]);
172
- * ```
173
- */
174
- setErrors(errors: ValidationError[]): void;
175
- /**
176
- * Очистить все errors (array-level + item-level)
177
- *
178
- * @example
179
- * ```typescript
180
- * arrayNode.clearErrors();
181
- * console.log(arrayNode.errors.value); // []
182
- * ```
183
- */
184
- clearErrors(): void;
185
- /**
186
- * Hook: вызывается после markAsTouched()
187
- *
188
- * Для ArrayNode: рекурсивно помечаем все элементы массива как touched
189
- */
190
- protected onMarkAsTouched(): void;
191
- /**
192
- * Hook: вызывается после markAsUntouched()
193
- *
194
- * Для ArrayNode: рекурсивно помечаем все элементы массива как untouched
195
- */
196
- protected onMarkAsUntouched(): void;
197
- /**
198
- * Hook: вызывается после markAsDirty()
199
- *
200
- * Для ArrayNode: рекурсивно помечаем все элементы массива как dirty
201
- */
202
- protected onMarkAsDirty(): void;
203
- /**
204
- * Hook: вызывается после markAsPristine()
205
- *
206
- * Для ArrayNode: рекурсивно помечаем все элементы массива как pristine
207
- */
208
- protected onMarkAsPristine(): void;
209
- /**
210
- * Итерировать по элементам массива
211
- * @param callback - Функция, вызываемая для каждого элемента с типизированным GroupNode proxy
212
- */
213
- forEach(callback: (item: FormProxy<T>, index: number) => void): void;
214
- /**
215
- * Маппинг элементов массива
216
- * @param callback - Функция преобразования с типизированным GroupNode proxy
217
- * @returns Новый массив результатов
218
- */
219
- map<R>(callback: (item: FormProxy<T>, index: number) => R): R[];
220
- /**
221
- * Создать новый элемент массива на основе схемы
222
- * @param initialValue - Начальные значения
223
- */
224
- private createItem;
225
- /**
226
- * Проверить, является ли схема групповой (объект полей)
227
- * @param schema - Схема для проверки
228
- */
229
- private isGroupSchema;
230
- /**
231
- * Применить validation schema ко всем элементам массива
232
- *
233
- * Validation schema будет применена к:
234
- * - Всем существующим элементам
235
- * - Всем новым элементам, добавляемым через push/insert
236
- *
237
- * @param schemaFn - Функция валидации для элемента массива
238
- *
239
- * @example
240
- * ```typescript
241
- * import { propertyValidation } from './validation/property-validation';
242
- *
243
- * form.properties.applyValidationSchema(propertyValidation);
244
- * ```
245
- */
246
- applyValidationSchema(schemaFn: unknown): void;
247
- /**
248
- * Применить behavior schema ко всем элементам ArrayNode
249
- *
250
- * Автоматически применяется к новым элементам при push/insert.
251
- *
252
- * @param schemaFn - Behavior schema функция
253
- *
254
- * @example
255
- * ```typescript
256
- * import { addressBehavior } from './behaviors/address-behavior';
257
- *
258
- * form.addresses.applyBehaviorSchema(addressBehavior);
259
- * ```
260
- */
261
- applyBehaviorSchema(schemaFn: unknown): void;
262
- /**
263
- * Подписка на изменения конкретного поля во всех элементах массива
264
- * Срабатывает при изменении значения поля в любом элементе
265
- *
266
- * @param fieldKey - Ключ поля для отслеживания
267
- * @param callback - Функция, вызываемая при изменении, получает массив всех значений и индекс измененного элемента
268
- * @returns Функция отписки для cleanup
269
- *
270
- * @example
271
- * ```typescript
272
- * // Автоматический пересчет общей стоимости при изменении цен
273
- * const dispose = form.existingLoans.watchItems(
274
- * 'remainingAmount',
275
- * (amounts) => {
276
- * const totalDebt = amounts.reduce((sum, amount) => sum + (amount || 0), 0);
277
- * form.totalDebt.setValue(totalDebt);
278
- * }
279
- * );
280
- *
281
- * // При изменении любого remainingAmount → пересчитается totalDebt
282
- * form.existingLoans.at(0)?.remainingAmount.setValue(500000);
283
- *
284
- * // Cleanup
285
- * useEffect(() => dispose, []);
286
- * ```
287
- */
288
- watchItems<K extends keyof T>(fieldKey: K, callback: (values: Array<T[K] | undefined>) => void | Promise<void>): () => void;
289
- /**
290
- * Подписка на изменение длины массива
291
- * Срабатывает при добавлении/удалении элементов
292
- *
293
- * @param callback - Функция, вызываемая при изменении длины, получает новую длину
294
- * @returns Функция отписки для cleanup
295
- *
296
- * @example
297
- * ```typescript
298
- * // Обновление счетчика элементов в UI
299
- * const dispose = form.properties.watchLength((length) => {
300
- * console.log(`Количество объектов недвижимости: ${length}`);
301
- * form.propertyCount.setValue(length);
302
- * });
303
- *
304
- * form.properties.push({ title: 'Квартира', value: 5000000 });
305
- * // Выведет: "Количество объектов недвижимости: 1"
306
- *
307
- * // Cleanup
308
- * useEffect(() => dispose, []);
309
- * ```
310
- */
311
- watchLength(callback: (length: number) => void | Promise<void>): () => void;
312
- /**
313
- * Очистить все ресурсы узла
314
- * Рекурсивно очищает все subscriptions и элементы массива
315
- *
316
- * @example
317
- * ```typescript
318
- * useEffect(() => {
319
- * return () => {
320
- * arrayNode.dispose();
321
- * };
322
- * }, []);
323
- * ```
324
- */
325
- dispose(): void;
326
- /**
327
- * Hook: вызывается после disable()
328
- *
329
- * Для ArrayNode: рекурсивно отключаем все элементы массива
330
- *
331
- * @example
332
- * ```typescript
333
- * // Отключить весь массив полей
334
- * form.items.disable();
335
- *
336
- * // Все элементы становятся disabled
337
- * form.items.forEach(item => {
338
- * console.log(item.status.value); // 'disabled'
339
- * });
340
- * ```
341
- */
342
- protected onDisable(): void;
343
- /**
344
- * Hook: вызывается после enable()
345
- *
346
- * Для ArrayNode: рекурсивно включаем все элементы массива
347
- *
348
- * @example
349
- * ```typescript
350
- * // Включить весь массив полей
351
- * form.items.enable();
352
- *
353
- * // Все элементы становятся enabled
354
- * form.items.forEach(item => {
355
- * console.log(item.status.value); // 'valid' или 'invalid'
356
- * });
357
- * ```
358
- */
359
- protected onEnable(): void;
360
- }