@reformer/core 8.0.0 → 9.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.
Files changed (52) hide show
  1. package/README.md +52 -57
  2. package/dist/behaviors-Br4Im38V.js +263 -0
  3. package/dist/behaviors.js +146 -146
  4. package/dist/core/factories/node-factory.d.ts +5 -4
  5. package/dist/core/model/behaviors.d.ts +15 -0
  6. package/dist/core/model/types.d.ts +41 -12
  7. package/dist/core/model/validate-model.d.ts +8 -4
  8. package/dist/core/nodes/field-node.d.ts +2 -2
  9. package/dist/core/nodes/group-node.d.ts +39 -3
  10. package/dist/core/nodes/model-array-node.d.ts +13 -1
  11. package/dist/core/types/deep-schema.d.ts +39 -5
  12. package/dist/core/types/form-proxy.d.ts +27 -2
  13. package/dist/core/types/index.d.ts +4 -10
  14. package/dist/core/types/schema-node.d.ts +79 -0
  15. package/dist/core/types/validation-schema.d.ts +37 -16
  16. package/dist/core/utils/create-form.d.ts +4 -3
  17. package/dist/core/utils/derived-registry.d.ts +29 -0
  18. package/dist/core/utils/error-handler.d.ts +4 -1
  19. package/dist/core/utils/form-submitter.d.ts +8 -4
  20. package/dist/core/utils/index.d.ts +1 -1
  21. package/dist/core/utils/safe-effect.d.ts +27 -7
  22. package/dist/core/utils/type-guards.d.ts +3 -3
  23. package/dist/core/validation/validators/date-utils.d.ts +5 -1
  24. package/dist/core/validation/validators/integer.d.ts +1 -1
  25. package/dist/core/validation/validators/is-number.d.ts +1 -1
  26. package/dist/core/validation/validators/max.d.ts +1 -1
  27. package/dist/core/validation/validators/min.d.ts +1 -1
  28. package/dist/core/validation/validators/multiple-of.d.ts +1 -1
  29. package/dist/core/validation/validators/non-negative.d.ts +1 -1
  30. package/dist/core/validation/validators/non-zero.d.ts +1 -1
  31. package/dist/core/validation/validators/required.d.ts +2 -1
  32. package/dist/{date-utils-xUWFslTj.js → date-utils-dTT_x_Be.js} +12 -10
  33. package/dist/hooks/types.d.ts +31 -1
  34. package/dist/hooks/useArrayLength.d.ts +1 -2
  35. package/dist/hooks/useFormControl.d.ts +2 -2
  36. package/dist/hooks/useSignalSubscription.d.ts +8 -1
  37. package/dist/index.js +625 -617
  38. package/dist/signals.d.ts +13 -0
  39. package/dist/signals.js +9 -0
  40. package/dist/validators/future-date.js +1 -1
  41. package/dist/validators/is-date.js +1 -1
  42. package/dist/validators/max-age.js +1 -1
  43. package/dist/validators/max-date.js +1 -1
  44. package/dist/validators/min-age.js +1 -1
  45. package/dist/validators/min-date.js +1 -1
  46. package/dist/validators/multiple-of.js +11 -7
  47. package/dist/validators/past-date.js +1 -1
  48. package/dist/validators/pattern.js +7 -6
  49. package/dist/validators/required.js +5 -9
  50. package/llms.txt +715 -175
  51. package/package.json +6 -2
  52. package/dist/behaviors-O9a1Djj9.js +0 -147
@@ -2,7 +2,7 @@ import { FormNode } from '../nodes/form-node';
2
2
  import { FieldNode } from '../nodes/field-node';
3
3
  import { GroupNode } from '../nodes/group-node';
4
4
  import { ArrayNode } from '../nodes/array-node';
5
- import { FormFields, FormValue } from '../types';
5
+ import { FormValue } from '../types';
6
6
  /**
7
7
  * Проверить, является ли значение любым FormNode
8
8
  *
@@ -61,7 +61,7 @@ export declare function isFieldNode(value: unknown): value is FieldNode<FormValu
61
61
  * }
62
62
  * ```
63
63
  */
64
- export declare function isGroupNode(value: unknown): value is GroupNode<FormFields>;
64
+ export declare function isGroupNode(value: unknown): value is GroupNode<object>;
65
65
  /**
66
66
  * Проверить, является ли значение ArrayNode (массив форм)
67
67
  *
@@ -80,7 +80,7 @@ export declare function isGroupNode(value: unknown): value is GroupNode<FormFiel
80
80
  * }
81
81
  * ```
82
82
  */
83
- export declare function isArrayNode(value: unknown): value is ArrayNode<FormFields>;
83
+ export declare function isArrayNode(value: unknown): value is ArrayNode<object>;
84
84
  /**
85
85
  * Получить тип узла как строку (для отладки)
86
86
  *
@@ -21,6 +21,10 @@ export declare function getToday(): Date;
21
21
  */
22
22
  export declare function normalizeDate(date: Date): Date;
23
23
  /**
24
- * Вычисляет возраст на основе даты рождения
24
+ * Вычисляет полный возраст годах) по календарным полям.
25
+ *
26
+ * Считаем по годам/месяцам/дням, а не делением миллисекунд на усреднённый год (365.25 дн): усреднение
27
+ * даёт off-by-one на границе — в день N-летия накопленных реальных дней меньше `N * 365.25`, и `floor`
28
+ * роняет возраст до `N - 1` (т.е. `minAge(18)` ошибочно отклонял 18-летнего в его день рождения).
25
29
  */
26
30
  export declare function calculateAge(birthDate: Date): number;
@@ -19,4 +19,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
19
19
  * },
20
20
  * ```
21
21
  */
22
- export declare function integer<TForm = unknown, TField extends number | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
22
+ export declare function integer<TForm = unknown, TField extends number | null | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
@@ -21,4 +21,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
21
21
  * },
22
22
  * ```
23
23
  */
24
- export declare function isNumber<TForm = unknown, TField extends number | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
24
+ export declare function isNumber<TForm = unknown, TField extends number | null | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
@@ -22,4 +22,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
22
22
  * },
23
23
  * ```
24
24
  */
25
- export declare function max<TForm = unknown, TField extends number | undefined = number>(maxValue: number, options?: ValidateOptions): Validator<TForm, TField>;
25
+ export declare function max<TForm = unknown, TField extends number | null | undefined = number>(maxValue: number, options?: ValidateOptions): Validator<TForm, TField>;
@@ -22,4 +22,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
22
22
  * },
23
23
  * ```
24
24
  */
25
- export declare function min<TForm = unknown, TField extends number | undefined = number>(minValue: number, options?: ValidateOptions): Validator<TForm, TField>;
25
+ export declare function min<TForm = unknown, TField extends number | null | undefined = number>(minValue: number, options?: ValidateOptions): Validator<TForm, TField>;
@@ -21,4 +21,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
21
21
  * },
22
22
  * ```
23
23
  */
24
- export declare function multipleOf<TForm = unknown, TField extends number | undefined = number>(divisor: number, options?: ValidateOptions): Validator<TForm, TField>;
24
+ export declare function multipleOf<TForm = unknown, TField extends number | null | undefined = number>(divisor: number, options?: ValidateOptions): Validator<TForm, TField>;
@@ -19,4 +19,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
19
19
  * },
20
20
  * ```
21
21
  */
22
- export declare function nonNegative<TForm = unknown, TField extends number | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
22
+ export declare function nonNegative<TForm = unknown, TField extends number | null | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
@@ -19,4 +19,4 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
19
19
  * },
20
20
  * ```
21
21
  */
22
- export declare function nonZero<TForm = unknown, TField extends number | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
22
+ export declare function nonZero<TForm = unknown, TField extends number | null | undefined = number>(options?: ValidateOptions): Validator<TForm, TField>;
@@ -4,7 +4,8 @@ import { Validator, ValidateOptions } from '../../types/validation-schema';
4
4
  *
5
5
  * Возвращает чистую функцию-валидатор `(value, control, root)`. Передаётся в `validate()`.
6
6
  *
7
- * Пустыми считаются: `null`, `undefined`, `''` (пустая строка).
7
+ * Пустыми считаются: `null`, `undefined`, `''` (пустая строка), `[]` (пустой массив —
8
+ * обязательный multi-select / FormArray без выбранных элементов).
8
9
  * Для boolean полей требуется значение `true`.
9
10
  *
10
11
  * @param options - Опции валидатора ({@link ValidateOptions}): `message`, `params`
@@ -1,4 +1,4 @@
1
- function r(t) {
1
+ function i(t) {
2
2
  if (t == null || t === "")
3
3
  return null;
4
4
  if (t instanceof Date)
@@ -9,21 +9,23 @@ function r(t) {
9
9
  }
10
10
  return null;
11
11
  }
12
- function e() {
12
+ function s() {
13
13
  const t = /* @__PURE__ */ new Date();
14
14
  return t.setHours(0, 0, 0, 0), t;
15
15
  }
16
- function o(t) {
16
+ function a(t) {
17
17
  const n = new Date(t);
18
18
  return n.setHours(0, 0, 0, 0), n;
19
19
  }
20
- function i(t) {
21
- const n = e();
22
- return Math.floor((n.getTime() - t.getTime()) / (365.25 * 24 * 60 * 60 * 1e3));
20
+ function c(t) {
21
+ const n = s(), e = a(t);
22
+ let r = n.getFullYear() - e.getFullYear();
23
+ const o = n.getMonth() - e.getMonth();
24
+ return (o < 0 || o === 0 && n.getDate() < e.getDate()) && (r -= 1), r;
23
25
  }
24
26
  export {
25
- i as c,
26
- e as g,
27
- o as n,
28
- r as p
27
+ c,
28
+ s as g,
29
+ a as n,
30
+ i as p
29
31
  };
@@ -190,7 +190,21 @@ export interface FieldControlState<T> {
190
190
  * );
191
191
  * ```
192
192
  */
193
- componentProps: Record<string, any>;
193
+ componentProps: Record<string, unknown>;
194
+ /**
195
+ * Флаг изменения поля.
196
+ * `true` когда значение поля отличается от начального.
197
+ *
198
+ * Реактивный аналог `control.dirty` — паритет с {@link ArrayControlState.dirty}.
199
+ *
200
+ * @example
201
+ * ```tsx
202
+ * const { dirty } = useFormControl(field);
203
+ *
204
+ * return dirty ? <span className="badge">Изменено</span> : null;
205
+ * ```
206
+ */
207
+ dirty: boolean;
194
208
  }
195
209
  /**
196
210
  * Состояние массива формы, возвращаемое хуком {@link useFormControl} для {@link ArrayNode}.
@@ -325,4 +339,20 @@ export interface ArrayControlState<T> {
325
339
  * ```
326
340
  */
327
341
  dirty: boolean;
342
+ /**
343
+ * Флаг отключения массива.
344
+ * `true` когда массив отключён (`ArrayNode.disable()`), в том числе через
345
+ * распространение disable от родительской группы.
346
+ *
347
+ * Используйте для отключения UI-действий добавления/удаления, когда массив
348
+ * структурно неизменяем.
349
+ *
350
+ * @example
351
+ * ```tsx
352
+ * const { disabled } = useFormControl(itemsArray);
353
+ *
354
+ * return <button disabled={disabled} onClick={() => control.push()}>Add</button>;
355
+ * ```
356
+ */
357
+ disabled: boolean;
328
358
  }
@@ -1,5 +1,4 @@
1
1
  import { ArrayNode } from '../core/nodes/array-node';
2
- import { FormFields } from '../core/types';
3
2
  /**
4
3
  * React-хук для подписки только на длину массива.
5
4
  *
@@ -28,4 +27,4 @@ import { FormFields } from '../core/types';
28
27
  *
29
28
  * @group React Hooks
30
29
  */
31
- export declare function useArrayLength<T extends FormFields>(control: ArrayNode<T>): number;
30
+ export declare function useArrayLength<T extends object>(control: ArrayNode<T>): number;
@@ -1,6 +1,6 @@
1
1
  import { FieldNode } from '../core/nodes/field-node';
2
2
  import { ArrayNode } from '../core/nodes/array-node';
3
- import { FormValue, FormFields } from '../core/types';
3
+ import { FormValue } from '../core/types';
4
4
  import { FieldControlState, ArrayControlState } from './types';
5
5
  /**
6
6
  * React-хук для подписки на состояние {@link ArrayNode}.
@@ -11,7 +11,7 @@ import { FieldControlState, ArrayControlState } from './types';
11
11
  *
12
12
  * @group React Hooks
13
13
  */
14
- export declare function useFormControl<T extends FormFields>(control: ArrayNode<T> | undefined): ArrayControlState<T>;
14
+ export declare function useFormControl<T extends object>(control: ArrayNode<T> | undefined): ArrayControlState<T>;
15
15
  /**
16
16
  * React-хук для подписки на состояние {@link FieldNode}.
17
17
  *
@@ -14,4 +14,11 @@ export interface SignalConfig<K extends string> {
14
14
  * Хук для подписки на набор сигналов с кешированием
15
15
  * @internal
16
16
  */
17
- export declare function useSignalSubscription<TSignals extends SignalMap, TSnapshot extends ExtractSignalValues<TSignals>>(signals: TSignals, configs: SignalConfig<Extract<keyof TSignals, string>>[], buildSnapshot: (values: ExtractSignalValues<TSignals>) => TSnapshot): TSnapshot;
17
+ export declare function useSignalSubscription<TSignals extends SignalMap, TSnapshot extends ExtractSignalValues<TSignals>>(signals: TSignals, configs: SignalConfig<Extract<keyof TSignals, string>>[], buildSnapshot: (values: ExtractSignalValues<TSignals>) => TSnapshot,
18
+ /**
19
+ * Стабильная идентичность подписки (обычно сам узел-контрол). subscribe/getSnapshot
20
+ * пересоздаются ТОЛЬКО при её смене, а не на каждом рендере — как у useFormControlValue,
21
+ * который ключует по `[control]`. Это убирает per-render churn (dispose+recreate preact-effect),
22
+ * сохраняя реактивность при подмене контрола на другой узел.
23
+ */
24
+ subscriptionKey?: unknown): TSnapshot;