@reformer/core 1.1.0 → 2.0.0-beta.2
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.
- package/dist/behaviors-DzYL8kY_.js +499 -0
- package/dist/behaviors.d.ts +6 -2
- package/dist/behaviors.js +19 -227
- package/dist/core/behavior/behavior-context.d.ts +6 -2
- package/dist/core/behavior/create-field-path.d.ts +3 -16
- package/dist/core/nodes/group-node.d.ts +14 -193
- package/dist/core/types/form-context.d.ts +10 -4
- package/dist/core/utils/field-path.d.ts +48 -0
- package/dist/core/utils/index.d.ts +1 -0
- package/dist/core/validation/core/validate-tree.d.ts +10 -4
- package/dist/core/validation/field-path.d.ts +3 -39
- package/dist/core/validation/validation-context.d.ts +23 -0
- package/dist/hooks/types.d.ts +328 -0
- package/dist/hooks/useFormControl.d.ts +13 -37
- package/dist/hooks/useFormControlValue.d.ts +167 -0
- package/dist/hooks/useSignalSubscription.d.ts +17 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +2886 -8
- package/dist/{create-field-path-CdPF3lIK.js → registry-helpers-BRxAr6nG.js} +133 -347
- package/dist/validators-gXoHPdqM.js +418 -0
- package/dist/validators.d.ts +6 -2
- package/dist/validators.js +29 -296
- package/llms.txt +1283 -22
- package/package.json +8 -4
- package/dist/core/behavior/behavior-applicator.d.ts +0 -71
- package/dist/core/behavior/behavior-applicator.js +0 -92
- package/dist/core/behavior/behavior-context.js +0 -38
- package/dist/core/behavior/behavior-registry.js +0 -198
- package/dist/core/behavior/behaviors/compute-from.js +0 -84
- package/dist/core/behavior/behaviors/copy-from.js +0 -64
- package/dist/core/behavior/behaviors/enable-when.js +0 -81
- package/dist/core/behavior/behaviors/index.js +0 -11
- package/dist/core/behavior/behaviors/reset-when.js +0 -63
- package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
- package/dist/core/behavior/behaviors/sync-fields.js +0 -66
- package/dist/core/behavior/behaviors/transform-value.js +0 -110
- package/dist/core/behavior/behaviors/watch-field.js +0 -56
- package/dist/core/behavior/compose-behavior.js +0 -166
- package/dist/core/behavior/create-field-path.js +0 -69
- package/dist/core/behavior/index.js +0 -17
- package/dist/core/behavior/types.js +0 -7
- package/dist/core/context/form-context-impl.js +0 -37
- package/dist/core/factories/index.js +0 -6
- package/dist/core/factories/node-factory.js +0 -281
- package/dist/core/nodes/array-node.js +0 -534
- package/dist/core/nodes/field-node.js +0 -510
- package/dist/core/nodes/form-node.js +0 -343
- package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
- package/dist/core/nodes/group-node/field-registry.js +0 -215
- package/dist/core/nodes/group-node/index.d.ts +0 -11
- package/dist/core/nodes/group-node/index.js +0 -11
- package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
- package/dist/core/nodes/group-node/proxy-builder.js +0 -161
- package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
- package/dist/core/nodes/group-node/state-manager.js +0 -265
- package/dist/core/nodes/group-node.js +0 -770
- package/dist/core/types/deep-schema.js +0 -11
- package/dist/core/types/field-path.js +0 -4
- package/dist/core/types/form-context.js +0 -25
- package/dist/core/types/group-node-proxy.js +0 -31
- package/dist/core/types/index.js +0 -4
- package/dist/core/types/validation-schema.js +0 -10
- package/dist/core/utils/create-form.js +0 -24
- package/dist/core/utils/debounce.js +0 -197
- package/dist/core/utils/error-handler.js +0 -226
- package/dist/core/utils/field-path-navigator.js +0 -374
- package/dist/core/utils/index.js +0 -14
- package/dist/core/utils/registry-helpers.js +0 -79
- package/dist/core/utils/registry-stack.js +0 -86
- package/dist/core/utils/resources.js +0 -69
- package/dist/core/utils/subscription-manager.js +0 -214
- package/dist/core/utils/type-guards.js +0 -169
- package/dist/core/validation/core/apply-when.js +0 -41
- package/dist/core/validation/core/apply.js +0 -38
- package/dist/core/validation/core/index.js +0 -8
- package/dist/core/validation/core/validate-async.js +0 -45
- package/dist/core/validation/core/validate-tree.js +0 -37
- package/dist/core/validation/core/validate.js +0 -38
- package/dist/core/validation/field-path.js +0 -147
- package/dist/core/validation/index.js +0 -33
- package/dist/core/validation/validate-form.js +0 -152
- package/dist/core/validation/validation-applicator.js +0 -217
- package/dist/core/validation/validation-context.js +0 -75
- package/dist/core/validation/validation-registry.js +0 -298
- package/dist/core/validation/validators/array-validators.js +0 -86
- package/dist/core/validation/validators/date.js +0 -117
- package/dist/core/validation/validators/email.js +0 -60
- package/dist/core/validation/validators/index.js +0 -14
- package/dist/core/validation/validators/max-length.js +0 -60
- package/dist/core/validation/validators/max.js +0 -60
- package/dist/core/validation/validators/min-length.js +0 -60
- package/dist/core/validation/validators/min.js +0 -60
- package/dist/core/validation/validators/number.js +0 -90
- package/dist/core/validation/validators/pattern.js +0 -62
- package/dist/core/validation/validators/phone.js +0 -58
- package/dist/core/validation/validators/required.js +0 -69
- package/dist/core/validation/validators/url.js +0 -55
- package/dist/hooks/useFormControl.js +0 -298
- 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
|
-
}
|