@reformer/core 2.0.0-beta.5 → 2.0.0-beta.6

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.
@@ -348,13 +348,22 @@ function Q(e, t, i) {
348
348
  const m = a.value.value;
349
349
  c || h(() => {
350
350
  c = !0;
351
- const U = s ? s(m) : m;
352
- r.setValue(U, { emitEvent: !1 }), c = !1;
351
+ try {
352
+ const U = s ? s(m) : m;
353
+ r.setValue(U, { emitEvent: !1 });
354
+ } finally {
355
+ c = !1;
356
+ }
353
357
  });
354
358
  }), b = g(() => {
355
359
  const m = r.value.value;
356
360
  c || h(() => {
357
- c = !0, a.setValue(m, { emitEvent: !1 }), c = !1;
361
+ c = !0;
362
+ try {
363
+ a.setValue(m, { emitEvent: !1 });
364
+ } finally {
365
+ c = !1;
366
+ }
358
367
  });
359
368
  });
360
369
  return () => {
package/dist/behaviors.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as s, b as r, g as t, c as o, m as l, i as h, f as n, e as i, k as m, j as p, s as c, t as d, l as f, n as F, h as y } from "./behaviors-DzYL8kY_.js";
1
+ import { a as s, b as r, g as t, c as o, m as l, i as h, f as n, e as i, k as m, j as p, s as c, t as d, l as f, n as F, h as y } from "./behaviors-2HSqHPb4.js";
2
2
  import { d as v, B, c as b } from "./registry-helpers-BRxAr6nG.js";
3
3
  export {
4
4
  v as BehaviorContextImpl,
@@ -49,6 +49,7 @@ export declare class FieldNode<T> extends FormNode<T> {
49
49
  private updateOn;
50
50
  private initialValue;
51
51
  private currentValidationId;
52
+ private currentAbortController?;
52
53
  private debounceMs;
53
54
  private validateDebounceTimer?;
54
55
  private validateDebounceResolve?;
@@ -137,12 +138,10 @@ export declare class FieldNode<T> extends FormNode<T> {
137
138
  * Немедленная валидация без debounce
138
139
  * @private
139
140
  * @remarks
140
- * Защищена от race conditions:
141
- * - Проверка validationId после синхронной валидации
142
- * - Проверка перед установкой pending
143
- * - Проверка после Promise.all
144
- * - Проверка перед обработкой async результатов
145
- * - Проверка перед очисткой errors
141
+ * Защищена от race conditions через AbortController:
142
+ * - Отменяет предыдущую валидацию при запуске новой
143
+ * - Передаёт AbortSignal в async валидаторы для отмены операций (например, fetch)
144
+ * - Проверяет signal.aborted в ключевых точках
146
145
  */
147
146
  private validateImmediate;
148
147
  setErrors(errors: ValidationError[]): void;
@@ -256,6 +255,13 @@ export declare class FieldNode<T> extends FormNode<T> {
256
255
  * Очистить все ресурсы и таймеры
257
256
  * Должен вызываться при unmount компонента
258
257
  *
258
+ * @remarks
259
+ * Освобождает все ресурсы:
260
+ * - Отписывает все subscriptions через SubscriptionManager
261
+ * - Очищает debounce таймер
262
+ * - Resolve'ит висячий debounce промис (предотвращает утечку памяти)
263
+ * - Отменяет текущую async валидацию через AbortController
264
+ *
259
265
  * @example
260
266
  * ```typescript
261
267
  * useEffect(() => {
@@ -20,12 +20,46 @@ export type UnknownFormValue = unknown;
20
20
  * @category Validation Types
21
21
  */
22
22
  export type ValidatorFn<T = FormValue> = (value: T) => ValidationError | null;
23
+ /**
24
+ * Опции для асинхронного валидатора
25
+ * @group Types
26
+ * @category Validation Types
27
+ */
28
+ export interface AsyncValidatorOptions {
29
+ /**
30
+ * AbortSignal для отмены валидации
31
+ * Позволяет отменить асинхронную операцию при новой валидации
32
+ */
33
+ signal?: AbortSignal;
34
+ }
23
35
  /**
24
36
  * Асинхронная функция валидации
37
+ *
38
+ * @param value - Значение для валидации
39
+ * @param options - Опции валидации (опционально)
40
+ * @returns Promise с ошибкой валидации или null если значение валидно
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * // Простой валидатор (без поддержки отмены)
45
+ * const emailExists: AsyncValidatorFn<string> = async (value) => {
46
+ * const exists = await checkEmail(value);
47
+ * return exists ? { code: 'exists', message: 'Email already exists' } : null;
48
+ * };
49
+ *
50
+ * // Валидатор с поддержкой отмены
51
+ * const emailExistsAbortable: AsyncValidatorFn<string> = async (value, options) => {
52
+ * const exists = await fetch(`/api/check-email?email=${value}`, {
53
+ * signal: options?.signal // Передаём signal в fetch для отмены запроса
54
+ * });
55
+ * return exists ? { code: 'exists', message: 'Email already exists' } : null;
56
+ * };
57
+ * ```
58
+ *
25
59
  * @group Types
26
60
  * @category Validation Types
27
61
  */
28
- export type AsyncValidatorFn<T = FormValue> = (value: T) => Promise<ValidationError | null>;
62
+ export type AsyncValidatorFn<T = FormValue> = (value: T, options?: AsyncValidatorOptions) => Promise<ValidationError | null>;
29
63
  /**
30
64
  * Ошибка валидации
31
65
  * @group Types