@reformer/core 1.1.0 → 2.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 (99) hide show
  1. package/dist/behaviors-DzYL8kY_.js +499 -0
  2. package/dist/behaviors.d.ts +6 -2
  3. package/dist/behaviors.js +19 -227
  4. package/dist/core/behavior/behavior-context.d.ts +6 -2
  5. package/dist/core/behavior/create-field-path.d.ts +3 -16
  6. package/dist/core/nodes/group-node.d.ts +14 -193
  7. package/dist/core/types/form-context.d.ts +10 -4
  8. package/dist/core/utils/field-path.d.ts +48 -0
  9. package/dist/core/utils/index.d.ts +1 -0
  10. package/dist/core/validation/core/validate-tree.d.ts +10 -4
  11. package/dist/core/validation/field-path.d.ts +3 -39
  12. package/dist/core/validation/validation-context.d.ts +23 -0
  13. package/dist/hooks/types.d.ts +328 -0
  14. package/dist/hooks/useFormControl.d.ts +13 -37
  15. package/dist/hooks/useFormControlValue.d.ts +167 -0
  16. package/dist/hooks/useSignalSubscription.d.ts +17 -0
  17. package/dist/index.d.ts +6 -1
  18. package/dist/index.js +2886 -8
  19. package/dist/{create-field-path-CdPF3lIK.js → registry-helpers-BRxAr6nG.js} +133 -347
  20. package/dist/validators-gXoHPdqM.js +418 -0
  21. package/dist/validators.d.ts +6 -2
  22. package/dist/validators.js +29 -296
  23. package/llms.txt +1283 -22
  24. package/package.json +8 -4
  25. package/dist/core/behavior/behavior-applicator.d.ts +0 -71
  26. package/dist/core/behavior/behavior-applicator.js +0 -92
  27. package/dist/core/behavior/behavior-context.js +0 -38
  28. package/dist/core/behavior/behavior-registry.js +0 -198
  29. package/dist/core/behavior/behaviors/compute-from.js +0 -84
  30. package/dist/core/behavior/behaviors/copy-from.js +0 -64
  31. package/dist/core/behavior/behaviors/enable-when.js +0 -81
  32. package/dist/core/behavior/behaviors/index.js +0 -11
  33. package/dist/core/behavior/behaviors/reset-when.js +0 -63
  34. package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
  35. package/dist/core/behavior/behaviors/sync-fields.js +0 -66
  36. package/dist/core/behavior/behaviors/transform-value.js +0 -110
  37. package/dist/core/behavior/behaviors/watch-field.js +0 -56
  38. package/dist/core/behavior/compose-behavior.js +0 -166
  39. package/dist/core/behavior/create-field-path.js +0 -69
  40. package/dist/core/behavior/index.js +0 -17
  41. package/dist/core/behavior/types.js +0 -7
  42. package/dist/core/context/form-context-impl.js +0 -37
  43. package/dist/core/factories/index.js +0 -6
  44. package/dist/core/factories/node-factory.js +0 -281
  45. package/dist/core/nodes/array-node.js +0 -534
  46. package/dist/core/nodes/field-node.js +0 -510
  47. package/dist/core/nodes/form-node.js +0 -343
  48. package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
  49. package/dist/core/nodes/group-node/field-registry.js +0 -215
  50. package/dist/core/nodes/group-node/index.d.ts +0 -11
  51. package/dist/core/nodes/group-node/index.js +0 -11
  52. package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
  53. package/dist/core/nodes/group-node/proxy-builder.js +0 -161
  54. package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
  55. package/dist/core/nodes/group-node/state-manager.js +0 -265
  56. package/dist/core/nodes/group-node.js +0 -770
  57. package/dist/core/types/deep-schema.js +0 -11
  58. package/dist/core/types/field-path.js +0 -4
  59. package/dist/core/types/form-context.js +0 -25
  60. package/dist/core/types/group-node-proxy.js +0 -31
  61. package/dist/core/types/index.js +0 -4
  62. package/dist/core/types/validation-schema.js +0 -10
  63. package/dist/core/utils/create-form.js +0 -24
  64. package/dist/core/utils/debounce.js +0 -197
  65. package/dist/core/utils/error-handler.js +0 -226
  66. package/dist/core/utils/field-path-navigator.js +0 -374
  67. package/dist/core/utils/index.js +0 -14
  68. package/dist/core/utils/registry-helpers.js +0 -79
  69. package/dist/core/utils/registry-stack.js +0 -86
  70. package/dist/core/utils/resources.js +0 -69
  71. package/dist/core/utils/subscription-manager.js +0 -214
  72. package/dist/core/utils/type-guards.js +0 -169
  73. package/dist/core/validation/core/apply-when.js +0 -41
  74. package/dist/core/validation/core/apply.js +0 -38
  75. package/dist/core/validation/core/index.js +0 -8
  76. package/dist/core/validation/core/validate-async.js +0 -45
  77. package/dist/core/validation/core/validate-tree.js +0 -37
  78. package/dist/core/validation/core/validate.js +0 -38
  79. package/dist/core/validation/field-path.js +0 -147
  80. package/dist/core/validation/index.js +0 -33
  81. package/dist/core/validation/validate-form.js +0 -152
  82. package/dist/core/validation/validation-applicator.js +0 -217
  83. package/dist/core/validation/validation-context.js +0 -75
  84. package/dist/core/validation/validation-registry.js +0 -298
  85. package/dist/core/validation/validators/array-validators.js +0 -86
  86. package/dist/core/validation/validators/date.js +0 -117
  87. package/dist/core/validation/validators/email.js +0 -60
  88. package/dist/core/validation/validators/index.js +0 -14
  89. package/dist/core/validation/validators/max-length.js +0 -60
  90. package/dist/core/validation/validators/max.js +0 -60
  91. package/dist/core/validation/validators/min-length.js +0 -60
  92. package/dist/core/validation/validators/min.js +0 -60
  93. package/dist/core/validation/validators/number.js +0 -90
  94. package/dist/core/validation/validators/pattern.js +0 -62
  95. package/dist/core/validation/validators/phone.js +0 -58
  96. package/dist/core/validation/validators/required.js +0 -69
  97. package/dist/core/validation/validators/url.js +0 -55
  98. package/dist/hooks/useFormControl.js +0 -298
  99. package/dist/node-factory-D7DOnSSN.js +0 -3200
@@ -1,298 +0,0 @@
1
- import { useSyncExternalStore, useCallback, useRef } from 'react';
2
- import { effect } from '@preact/signals-core';
3
- // ============================================================================
4
- // Утилиты для сравнения
5
- // ============================================================================
6
- /**
7
- * Shallow сравнение массивов по содержимому
8
- * Возвращает true если массивы равны (одинаковые элементы в том же порядке)
9
- * @internal
10
- */
11
- function shallowArrayEqual(a, b) {
12
- if (a === b)
13
- return true;
14
- if (a.length !== b.length)
15
- return false;
16
- for (let i = 0; i < a.length; i++) {
17
- if (a[i] !== b[i])
18
- return false;
19
- }
20
- return true;
21
- }
22
- // ============================================================================
23
- // Внутренние хуки для каждого типа контрола
24
- // ============================================================================
25
- /**
26
- * Внутренний хук для FieldNode с использованием useSyncExternalStore
27
- * @internal
28
- */
29
- function useFieldControl(control) {
30
- // Кеш для предотвращения лишних ре-рендеров
31
- const cacheRef = useRef({
32
- snapshot: null,
33
- value: control.value.value,
34
- errors: control.errors.value,
35
- componentProps: control.componentProps.value,
36
- disabled: control.disabled.value,
37
- pending: control.pending.value,
38
- valid: control.valid.value,
39
- invalid: control.invalid.value,
40
- touched: control.touched.value,
41
- shouldShowError: control.shouldShowError.value,
42
- });
43
- // Функция подписки - использует effect для отслеживания всех сигналов
44
- const subscribe = useCallback((onStoreChange) => {
45
- // Используем effect который автоматически отслеживает все читаемые сигналы
46
- // effect НЕ вызывает callback сразу, только при изменениях
47
- let isFirstRun = true;
48
- const dispose = effect(() => {
49
- // Читаем все сигналы чтобы effect их отслеживал
50
- control.value.value;
51
- control.disabled.value;
52
- control.errors.value;
53
- control.pending.value;
54
- control.valid.value;
55
- control.invalid.value;
56
- control.touched.value;
57
- control.shouldShowError.value;
58
- control.componentProps.value;
59
- // Пропускаем первый вызов (при создании effect)
60
- if (isFirstRun) {
61
- isFirstRun = false;
62
- return;
63
- }
64
- // Уведомляем React об изменении
65
- onStoreChange();
66
- });
67
- return dispose;
68
- }, [control]);
69
- // Функция получения текущего состояния
70
- const getSnapshot = useCallback(() => {
71
- const cache = cacheRef.current;
72
- // Получаем текущие значения из сигналов
73
- const currentValue = control.value.value;
74
- const currentErrors = control.errors.value;
75
- const currentComponentProps = control.componentProps.value;
76
- const currentDisabled = control.disabled.value;
77
- const currentPending = control.pending.value;
78
- const currentValid = control.valid.value;
79
- const currentInvalid = control.invalid.value;
80
- const currentTouched = control.touched.value;
81
- const currentShouldShowError = control.shouldShowError.value;
82
- // Проверяем, изменилось ли что-то
83
- // Используем shallowArrayEqual для errors т.к. валидация может создавать новые массивы
84
- const hasChanged = cache.value !== currentValue ||
85
- !shallowArrayEqual(cache.errors, currentErrors) ||
86
- cache.componentProps !== currentComponentProps ||
87
- cache.disabled !== currentDisabled ||
88
- cache.pending !== currentPending ||
89
- cache.valid !== currentValid ||
90
- cache.invalid !== currentInvalid ||
91
- cache.touched !== currentTouched ||
92
- cache.shouldShowError !== currentShouldShowError;
93
- // Если ничего не изменилось, возвращаем кешированный snapshot
94
- if (!hasChanged && cache.snapshot) {
95
- return cache.snapshot;
96
- }
97
- // Обновляем кеш
98
- cache.value = currentValue;
99
- cache.errors = currentErrors;
100
- cache.componentProps = currentComponentProps;
101
- cache.disabled = currentDisabled;
102
- cache.pending = currentPending;
103
- cache.valid = currentValid;
104
- cache.invalid = currentInvalid;
105
- cache.touched = currentTouched;
106
- cache.shouldShowError = currentShouldShowError;
107
- // Создаём новый snapshot
108
- cache.snapshot = {
109
- value: currentValue,
110
- pending: currentPending,
111
- disabled: currentDisabled,
112
- errors: currentErrors,
113
- valid: currentValid,
114
- invalid: currentInvalid,
115
- touched: currentTouched,
116
- shouldShowError: currentShouldShowError,
117
- componentProps: currentComponentProps,
118
- };
119
- return cache.snapshot;
120
- }, [control]);
121
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
122
- }
123
- /**
124
- * Внутренний хук для ArrayNode с использованием useSyncExternalStore
125
- * @internal
126
- */
127
- function useArrayControl(control) {
128
- // Кеш для предотвращения лишних ре-рендеров
129
- const cacheRef = useRef({
130
- snapshot: null,
131
- value: control.value.value,
132
- length: control.length.value,
133
- errors: control.errors.value,
134
- pending: control.pending.value,
135
- valid: control.valid.value,
136
- invalid: control.invalid.value,
137
- touched: control.touched.value,
138
- dirty: control.dirty.value,
139
- });
140
- // Функция подписки
141
- const subscribe = useCallback((onStoreChange) => {
142
- let isFirstRun = true;
143
- const dispose = effect(() => {
144
- // Читаем все сигналы
145
- control.value.value;
146
- control.length.value;
147
- control.errors.value;
148
- control.pending.value;
149
- control.valid.value;
150
- control.invalid.value;
151
- control.touched.value;
152
- control.dirty.value;
153
- if (isFirstRun) {
154
- isFirstRun = false;
155
- return;
156
- }
157
- onStoreChange();
158
- });
159
- return dispose;
160
- }, [control]);
161
- // Функция получения текущего состояния
162
- const getSnapshot = useCallback(() => {
163
- const cache = cacheRef.current;
164
- const currentValue = control.value.value;
165
- const currentLength = control.length.value;
166
- const currentErrors = control.errors.value;
167
- const currentPending = control.pending.value;
168
- const currentValid = control.valid.value;
169
- const currentInvalid = control.invalid.value;
170
- const currentTouched = control.touched.value;
171
- const currentDirty = control.dirty.value;
172
- const hasChanged = cache.value !== currentValue ||
173
- cache.length !== currentLength ||
174
- !shallowArrayEqual(cache.errors, currentErrors) ||
175
- cache.pending !== currentPending ||
176
- cache.valid !== currentValid ||
177
- cache.invalid !== currentInvalid ||
178
- cache.touched !== currentTouched ||
179
- cache.dirty !== currentDirty;
180
- if (!hasChanged && cache.snapshot) {
181
- return cache.snapshot;
182
- }
183
- cache.value = currentValue;
184
- cache.length = currentLength;
185
- cache.errors = currentErrors;
186
- cache.pending = currentPending;
187
- cache.valid = currentValid;
188
- cache.invalid = currentInvalid;
189
- cache.touched = currentTouched;
190
- cache.dirty = currentDirty;
191
- cache.snapshot = {
192
- value: currentValue,
193
- length: currentLength,
194
- pending: currentPending,
195
- errors: currentErrors,
196
- valid: currentValid,
197
- invalid: currentInvalid,
198
- touched: currentTouched,
199
- dirty: currentDirty,
200
- };
201
- return cache.snapshot;
202
- }, [control]);
203
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
204
- }
205
- // ============================================================================
206
- // Хук для получения только значения (без подписки на другие сигналы)
207
- // ============================================================================
208
- /**
209
- * Хук для получения только значения поля без подписки на errors, valid и т.д.
210
- * Используйте когда нужно только значение для условного рендеринга.
211
- *
212
- * @group React Hooks
213
- */
214
- export function useFormControlValue(control) {
215
- const cacheRef = useRef({
216
- value: control.value.value,
217
- snapshot: control.value.value,
218
- });
219
- const subscribe = useCallback((onStoreChange) => {
220
- let isFirstRun = true;
221
- const dispose = effect(() => {
222
- control.value.value; // Подписываемся ТОЛЬКО на value
223
- if (isFirstRun) {
224
- isFirstRun = false;
225
- return;
226
- }
227
- onStoreChange();
228
- });
229
- return dispose;
230
- }, [control]);
231
- const getSnapshot = useCallback(() => {
232
- const currentValue = control.value.value;
233
- if (cacheRef.current.value === currentValue) {
234
- return cacheRef.current.snapshot;
235
- }
236
- cacheRef.current.value = currentValue;
237
- cacheRef.current.snapshot = currentValue;
238
- return currentValue;
239
- }, [control]);
240
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
241
- }
242
- /**
243
- * Хук для работы с FieldNode или ArrayNode - возвращает состояние с подписками на сигналы
244
- *
245
- * Использует useSyncExternalStore для оптимальной интеграции с React 18+.
246
- * Компонент ре-рендерится только когда реально изменились данные контрола.
247
- *
248
- * @group React Hooks
249
- *
250
- * @example FieldNode
251
- * ```tsx
252
- * const { value, errors, componentProps } = useFormControl(control);
253
- *
254
- * return (
255
- * <div>
256
- * <input value={value} onChange={e => control.setValue(e.target.value)} />
257
- * {errors.length > 0 && <span>{errors[0].message}</span>}
258
- * </div>
259
- * );
260
- * ```
261
- *
262
- * @example ArrayNode
263
- * ```tsx
264
- * const { length } = useFormControl(arrayControl);
265
- *
266
- * return (
267
- * <div>
268
- * {arrayControl.map((item, index) => (
269
- * <ItemComponent key={item.id || index} control={item} />
270
- * ))}
271
- * {length === 0 && <span>Список пуст</span>}
272
- * </div>
273
- * );
274
- * ```
275
- */
276
- export function useFormControl(control) {
277
- // Определяем тип контрола по наличию специфичных свойств
278
- const isArrayNode = control && 'length' in control && 'map' in control;
279
- // Для undefined контрола возвращаем дефолтное состояние
280
- if (!control) {
281
- return {
282
- value: [],
283
- length: 0,
284
- pending: false,
285
- errors: [],
286
- valid: true,
287
- invalid: false,
288
- touched: false,
289
- dirty: false,
290
- };
291
- }
292
- if (isArrayNode) {
293
- // eslint-disable-next-line react-hooks/rules-of-hooks
294
- return useArrayControl(control);
295
- }
296
- // eslint-disable-next-line react-hooks/rules-of-hooks
297
- return useFieldControl(control);
298
- }