@reformer/core 11.0.0-beta.3 → 11.0.0-beta.4

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 (113) hide show
  1. package/dist/behaviors.d.ts +1 -1
  2. package/dist/behaviors.js +37 -37
  3. package/dist/create-model-Dxh9cfLp.js +97 -0
  4. package/dist/form/behaviors/collections.d.ts +50 -0
  5. package/dist/form/behaviors/context.d.ts +23 -0
  6. package/dist/form/behaviors/index.d.ts +28 -0
  7. package/dist/form/behaviors/internals.d.ts +26 -0
  8. package/dist/form/{behaviors-node.d.ts → behaviors/node.d.ts} +3 -3
  9. package/dist/form/behaviors/operators.d.ts +51 -0
  10. package/dist/form/behaviors/types.d.ts +17 -0
  11. package/dist/form/create-core-form.d.ts +3 -3
  12. package/dist/form/create-form.d.ts +1 -1
  13. package/dist/form/index.d.ts +10 -16
  14. package/dist/form/nodes/model-array-node.d.ts +1 -1
  15. package/dist/form/types/contracts.d.ts +9 -6
  16. package/dist/form/types/validation-schema.d.ts +1 -1
  17. package/dist/form/{validation-config.d.ts → validation/config.d.ts} +3 -3
  18. package/dist/form/validation/context.d.ts +27 -0
  19. package/dist/form/{error-handler.d.ts → validation/error-handler.d.ts} +1 -1
  20. package/dist/form/validation/index.d.ts +23 -28
  21. package/dist/form/validation/operators.d.ts +42 -0
  22. package/dist/form/validation/run.d.ts +45 -0
  23. package/dist/form/{validation-strategy.d.ts → validation/strategy.d.ts} +2 -2
  24. package/dist/form/validation/types.d.ts +28 -0
  25. package/dist/form/{validation/validators → validators}/date-utils.d.ts +1 -1
  26. package/dist/form/{validation/validators → validators}/email.d.ts +1 -1
  27. package/dist/form/{validation/validators → validators}/file-type.d.ts +1 -1
  28. package/dist/form/{validation/validators → validators}/file-utils.d.ts +1 -1
  29. package/dist/form/{validation/validators → validators}/future-date.d.ts +1 -1
  30. package/dist/form/{validation/validators → validators}/index.d.ts +6 -4
  31. package/dist/form/{validation/validators → validators}/integer.d.ts +1 -1
  32. package/dist/form/{validation/validators → validators}/is-date.d.ts +1 -1
  33. package/dist/form/{validation/validators → validators}/is-number.d.ts +1 -1
  34. package/dist/form/{validation/validators → validators}/max-age.d.ts +1 -1
  35. package/dist/form/{validation/validators → validators}/max-date.d.ts +1 -1
  36. package/dist/form/{validation/validators → validators}/max-file-size.d.ts +1 -1
  37. package/dist/form/{validation/validators → validators}/max-files.d.ts +1 -1
  38. package/dist/form/{validation/validators → validators}/max-length.d.ts +1 -1
  39. package/dist/form/{validation/validators → validators}/max-total-file-size.d.ts +1 -1
  40. package/dist/form/{validation/validators → validators}/max.d.ts +1 -1
  41. package/dist/form/{validation/validators → validators}/min-age.d.ts +1 -1
  42. package/dist/form/{validation/validators → validators}/min-date.d.ts +1 -1
  43. package/dist/form/{validation/validators → validators}/min-file-size.d.ts +1 -1
  44. package/dist/form/{validation/validators → validators}/min-files.d.ts +1 -1
  45. package/dist/form/{validation/validators → validators}/min-length.d.ts +1 -1
  46. package/dist/form/{validation/validators → validators}/min.d.ts +1 -1
  47. package/dist/form/{validation/validators → validators}/multiple-of.d.ts +1 -1
  48. package/dist/form/{validation/validators → validators}/non-negative.d.ts +1 -1
  49. package/dist/form/{validation/validators → validators}/non-zero.d.ts +1 -1
  50. package/dist/form/{validation/validators → validators}/past-date.d.ts +1 -1
  51. package/dist/form/{validation/validators → validators}/pattern.d.ts +1 -1
  52. package/dist/form/{validation/validators → validators}/phone.d.ts +1 -1
  53. package/dist/form/{validation/validators → validators}/required.d.ts +1 -1
  54. package/dist/form/{validation/validators → validators}/url.d.ts +1 -1
  55. package/dist/index.d.ts +7 -4
  56. package/dist/index.js +246 -71
  57. package/dist/{state/form-model.d.ts → model/create-model.d.ts} +0 -14
  58. package/dist/{state → model}/index.d.ts +10 -11
  59. package/dist/model/model-nodes.d.ts +60 -0
  60. package/dist/model/model-signals-proxy.d.ts +32 -0
  61. package/dist/model/model-value-proxy.d.ts +3 -0
  62. package/dist/{state → model}/safe-effect.d.ts +1 -1
  63. package/dist/model-signals-proxy-mV3WGdlO.js +233 -0
  64. package/dist/model.d.ts +2 -0
  65. package/dist/model.js +21 -0
  66. package/dist/{form → platforms/react}/hooks/types.d.ts +1 -1
  67. package/dist/{form → platforms/react}/hooks/use-form-bundle.d.ts +1 -1
  68. package/dist/{form → platforms/react}/hooks/use-form-validation.d.ts +3 -3
  69. package/dist/{form → platforms/react}/hooks/useArrayLength.d.ts +1 -1
  70. package/dist/{form → platforms/react}/hooks/useFormControl.d.ts +3 -3
  71. package/dist/{form → platforms/react}/hooks/useFormControlValue.d.ts +2 -2
  72. package/dist/platforms/react/index.d.ts +23 -0
  73. package/dist/signals.d.ts +1 -1
  74. package/dist/strategy-DA3JwxsR.js +170 -0
  75. package/dist/validation.d.ts +1 -1
  76. package/dist/validation.js +10 -165
  77. package/dist/validators/email.d.ts +1 -1
  78. package/dist/validators/future-date.d.ts +1 -1
  79. package/dist/validators/integer.d.ts +1 -1
  80. package/dist/validators/is-date.d.ts +1 -1
  81. package/dist/validators/is-number.d.ts +1 -1
  82. package/dist/validators/max-age.d.ts +1 -1
  83. package/dist/validators/max-date.d.ts +1 -1
  84. package/dist/validators/max-length.d.ts +1 -1
  85. package/dist/validators/max.d.ts +1 -1
  86. package/dist/validators/min-age.d.ts +1 -1
  87. package/dist/validators/min-date.d.ts +1 -1
  88. package/dist/validators/min-length.d.ts +1 -1
  89. package/dist/validators/min.d.ts +1 -1
  90. package/dist/validators/multiple-of.d.ts +1 -1
  91. package/dist/validators/non-negative.d.ts +1 -1
  92. package/dist/validators/non-zero.d.ts +1 -1
  93. package/dist/validators/past-date.d.ts +1 -1
  94. package/dist/validators/pattern.d.ts +1 -1
  95. package/dist/validators/phone.d.ts +1 -1
  96. package/dist/validators/required.d.ts +1 -1
  97. package/dist/validators/url.d.ts +1 -1
  98. package/dist/validators.d.ts +1 -1
  99. package/llms.txt +64 -43
  100. package/package.json +4 -4
  101. package/dist/form/behaviors.d.ts +0 -133
  102. package/dist/form/validation-schema.d.ts +0 -106
  103. package/dist/form/validators.d.ts +0 -11
  104. package/dist/form-model-DhW2HZOB.js +0 -323
  105. package/dist/state.d.ts +0 -2
  106. package/dist/state.js +0 -21
  107. package/dist/subscription-manager-705bls97.js +0 -171
  108. /package/dist/{state → form/nodes}/subscription-manager.d.ts +0 -0
  109. /package/dist/{state → model}/behaviors-value.d.ts +0 -0
  110. /package/dist/{state → model}/derived-registry.d.ts +0 -0
  111. /package/dist/{state → model}/types.d.ts +0 -0
  112. /package/dist/{behaviors-node-DGEFMTQu.js → node-DGEFMTQu.js} +0 -0
  113. /package/dist/{form → platforms/react}/hooks/useSignalSubscription.d.ts +0 -0
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
- import { a as G, c as ee } from "./form-model-DhW2HZOB.js";
2
- import { i as Ke, m as He, u as Ye } from "./form-model-DhW2HZOB.js";
3
- import { c as Je, a as Qe, r as Xe, b as Ze, d as et, e as tt, f as st, s as rt, t as it, w as nt } from "./behaviors-value-C7dSEhCc.js";
4
- import { S as L } from "./subscription-manager-705bls97.js";
1
+ import { c as ee } from "./create-model-Dxh9cfLp.js";
2
+ import { e as Ke } from "./create-model-Dxh9cfLp.js";
3
+ import { a as G } from "./model-signals-proxy-mV3WGdlO.js";
4
+ import { i as ze, m as Ye, u as Je } from "./model-signals-proxy-mV3WGdlO.js";
5
+ import { c as Xe, a as Ze, r as et, b as tt, d as st, e as rt, f as it, s as nt, t as at, w as ot } from "./behaviors-value-C7dSEhCc.js";
5
6
  import { signal as g, computed as m, effect as _, batch as te, Signal as j } from "@preact/signals-core";
6
7
  import { r as se } from "./signal-node-registry-tiwel-TV.js";
7
- import { g as ot } from "./signal-node-registry-tiwel-TV.js";
8
- import { defineValidationSchema as re, createFormValidation as D, validateModel as ie, apply as ne } from "./validation.js";
9
- import Y, { useState as ae, useEffect as z, useRef as V, useCallback as E, useMemo as oe } from "react";
10
- import { d as ut, e as dt } from "./behaviors-node-DGEFMTQu.js";
8
+ import { g as ut } from "./signal-node-registry-tiwel-TV.js";
9
+ import { f as re, h as D, g as ie, d as ne } from "./strategy-DA3JwxsR.js";
10
+ import { d as ct, e as ht } from "./node-DGEFMTQu.js";
11
+ import z, { useRef as k, useCallback as E, useMemo as ae, useEffect as Y, useState as oe } from "react";
11
12
  class M {
12
13
  // ============================================================================
13
14
  // Protected состояние (для Template Method паттерна)
@@ -273,6 +274,174 @@ class M {
273
274
  onEnable() {
274
275
  }
275
276
  }
277
+ class L {
278
+ /**
279
+ * Хранилище подписок
280
+ * Ключ: уникальный идентификатор подписки
281
+ * Значение: функция отписки (dispose)
282
+ */
283
+ subscriptions = /* @__PURE__ */ new Map();
284
+ /**
285
+ * Добавляет подписку
286
+ *
287
+ * Если подписка с таким ключом уже существует, отписывается от неё
288
+ * и заменяет новой. Это предотвращает утечки памяти при повторной
289
+ * регистрации подписки с тем же ключом.
290
+ *
291
+ * @param key Уникальный ключ подписки
292
+ * @param dispose Функция отписки (обычно возвращаемая из effect())
293
+ * @returns Функция для отписки от этой конкретной подписки
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * const manager = new SubscriptionManager();
298
+ *
299
+ * // Добавление подписки
300
+ * const unsubscribe = manager.add('mySubscription', () => {
301
+ * console.log('Disposing subscription');
302
+ * });
303
+ *
304
+ * // Отписка через возвращаемую функцию
305
+ * unsubscribe();
306
+ *
307
+ * // Или через manager.remove()
308
+ * manager.add('anotherSub', disposeFn);
309
+ * manager.remove('anotherSub');
310
+ * ```
311
+ */
312
+ add(e, t) {
313
+ return this.subscriptions.has(e) && (process.env.NODE_ENV !== "production" && console.warn(`[SubscriptionManager] Subscription "${e}" already exists, replacing`), this.subscriptions.get(e)?.()), this.subscriptions.set(e, t), () => this.remove(e);
314
+ }
315
+ /**
316
+ * Удаляет подписку по ключу
317
+ *
318
+ * Вызывает функцию отписки и удаляет подписку из хранилища.
319
+ * Если подписка с таким ключом не найдена, ничего не делает.
320
+ *
321
+ * @param key Ключ подписки
322
+ * @returns true, если подписка была удалена, false если не найдена
323
+ *
324
+ * @example
325
+ * ```typescript
326
+ * const manager = new SubscriptionManager();
327
+ * manager.add('mySub', disposeFn);
328
+ *
329
+ * // Удаление подписки
330
+ * const removed = manager.remove('mySub'); // true
331
+ *
332
+ * // Попытка удалить несуществующую подписку
333
+ * const removed2 = manager.remove('nonExistent'); // false
334
+ * ```
335
+ */
336
+ remove(e) {
337
+ const t = this.subscriptions.get(e);
338
+ return t ? (t(), this.subscriptions.delete(e), !0) : !1;
339
+ }
340
+ /**
341
+ * Очищает все подписки
342
+ *
343
+ * Вызывает функции отписки для всех активных подписок
344
+ * и очищает хранилище. Обычно используется при dispose узла формы.
345
+ *
346
+ * @example
347
+ * ```typescript
348
+ * class FieldNode {
349
+ * private subscriptions = new SubscriptionManager();
350
+ *
351
+ * dispose() {
352
+ * // Отписываемся от всех effect
353
+ * this.subscriptions.clear();
354
+ * }
355
+ * }
356
+ * ```
357
+ */
358
+ clear() {
359
+ this.subscriptions.forEach((e) => {
360
+ e();
361
+ }), this.subscriptions.clear();
362
+ }
363
+ /**
364
+ * Возвращает количество активных подписок
365
+ *
366
+ * Полезно для отладки утечек памяти. Если количество подписок
367
+ * растет без ограничений, это может указывать на то, что
368
+ * компоненты не отписываются должным образом.
369
+ *
370
+ * @returns Количество активных подписок
371
+ *
372
+ * @example
373
+ * ```typescript
374
+ * const manager = new SubscriptionManager();
375
+ * console.log(manager.size()); // 0
376
+ *
377
+ * manager.add('sub1', disposeFn1);
378
+ * manager.add('sub2', disposeFn2);
379
+ * console.log(manager.size()); // 2
380
+ *
381
+ * manager.clear();
382
+ * console.log(manager.size()); // 0
383
+ * ```
384
+ */
385
+ size() {
386
+ return this.subscriptions.size;
387
+ }
388
+ /**
389
+ * Проверяет, есть ли подписка с данным ключом
390
+ *
391
+ * @param key Ключ подписки
392
+ * @returns true, если подписка существует
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * const manager = new SubscriptionManager();
397
+ * manager.add('mySub', disposeFn);
398
+ *
399
+ * console.log(manager.has('mySub')); // true
400
+ * console.log(manager.has('nonExistent')); // false
401
+ * ```
402
+ */
403
+ has(e) {
404
+ return this.subscriptions.has(e);
405
+ }
406
+ /**
407
+ * Возвращает список всех ключей активных подписок
408
+ *
409
+ * Полезно для отладки: можно увидеть, какие подписки активны.
410
+ *
411
+ * @returns Массив ключей всех активных подписок
412
+ *
413
+ * @example
414
+ * ```typescript
415
+ * const manager = new SubscriptionManager();
416
+ * manager.add('watch-value', disposeFn1);
417
+ * manager.add('watch-errors', disposeFn2);
418
+ *
419
+ * console.log(manager.getKeys()); // ['watch-value', 'watch-errors']
420
+ * ```
421
+ */
422
+ getKeys() {
423
+ return Array.from(this.subscriptions.keys());
424
+ }
425
+ /**
426
+ * Отписывается от всех подписок (алиас для clear())
427
+ *
428
+ * Используется при dispose() узла формы для совместимости с ожидаемым API.
429
+ *
430
+ * @example
431
+ * ```typescript
432
+ * class FieldNode {
433
+ * private subscriptions = new SubscriptionManager();
434
+ *
435
+ * dispose() {
436
+ * this.subscriptions.dispose();
437
+ * }
438
+ * }
439
+ * ```
440
+ */
441
+ dispose() {
442
+ this.clear();
443
+ }
444
+ }
276
445
  const O = {
277
446
  /** FieldNode.watch() */
278
447
  Watch: "watch",
@@ -284,11 +453,11 @@ const O = {
284
453
  WatchField: "watchField"
285
454
  };
286
455
  let le = 0;
287
- function F(s) {
456
+ function N(s) {
288
457
  return `${s}-${++le}`;
289
458
  }
290
459
  var S = /* @__PURE__ */ ((s) => (s.THROW = "throw", s.LOG = "log", s.CONVERT = "convert", s))(S || {});
291
- class k {
460
+ class V {
292
461
  static handle(e, t, r = "throw") {
293
462
  const i = this.extractMessage(e);
294
463
  switch (process.env.NODE_ENV !== "production" && console.error(`[${t}]`, e), r) {
@@ -712,7 +881,7 @@ class de extends M {
712
881
  } catch (u) {
713
882
  if (u instanceof DOMException && u.name === "AbortError")
714
883
  throw u;
715
- return k.handle(
884
+ return V.handle(
716
885
  u,
717
886
  "FieldNode AsyncValidator",
718
887
  S.CONVERT
@@ -859,7 +1028,7 @@ class de extends M {
859
1028
  const t = new AbortController(), r = _(() => {
860
1029
  const n = this.value.value;
861
1030
  e(n, t.signal);
862
- }), i = F(O.Watch);
1031
+ }), i = N(O.Watch);
863
1032
  return this.disposers.add(i, () => {
864
1033
  t.abort(), r();
865
1034
  });
@@ -890,7 +1059,7 @@ class de extends M {
890
1059
  const r = _(() => {
891
1060
  const n = e.map((l) => l.value), a = t(...n);
892
1061
  this.setValue(a, { emitEvent: !1 });
893
- }), i = F(O.ComputeFrom);
1062
+ }), i = N(O.ComputeFrom);
894
1063
  return this.disposers.add(i, r);
895
1064
  }
896
1065
  /**
@@ -1411,7 +1580,7 @@ class A extends M {
1411
1580
  const a = _(() => {
1412
1581
  const d = i.value.value, u = r ? r(d) : d;
1413
1582
  n.setValue(u, { emitEvent: !1 });
1414
- }), l = F(O.LinkFields);
1583
+ }), l = N(O.LinkFields);
1415
1584
  return this.disposers.add(l, a);
1416
1585
  }
1417
1586
  /**
@@ -1448,7 +1617,7 @@ class A extends M {
1448
1617
  throw new Error(`GroupNode.watchField: field "${e}" not found`);
1449
1618
  const i = _(() => {
1450
1619
  t(r.value.value);
1451
- }), n = F(O.WatchField);
1620
+ }), n = N(O.WatchField);
1452
1621
  return this.disposers.add(n, i);
1453
1622
  }
1454
1623
  /**
@@ -1461,7 +1630,7 @@ class A extends M {
1461
1630
  throw new Error(`GroupNode.watchFieldByPath: field "${e}" not found`);
1462
1631
  const i = _(() => {
1463
1632
  t(r.value.value);
1464
- }), n = F(O.WatchField);
1633
+ }), n = N(O.WatchField);
1465
1634
  return this.disposers.add(n, i);
1466
1635
  }
1467
1636
  /**
@@ -1561,7 +1730,7 @@ class W extends M {
1561
1730
  */
1562
1731
  removeAt(e) {
1563
1732
  if (e < 0 || e >= this.items.value.length) {
1564
- k.handle(
1733
+ V.handle(
1565
1734
  new Error(
1566
1735
  `ArrayNode.removeAt: index ${e} out of bounds (length: ${this.items.value.length})`
1567
1736
  ),
@@ -1580,7 +1749,7 @@ class W extends M {
1580
1749
  */
1581
1750
  insert(e, t) {
1582
1751
  if (e < 0 || e > this.items.value.length) {
1583
- k.handle(
1752
+ V.handle(
1584
1753
  new Error(
1585
1754
  `ArrayNode.insert: index ${e} out of bounds (length: ${this.items.value.length})`
1586
1755
  ),
@@ -1611,7 +1780,7 @@ class W extends M {
1611
1780
  move(e, t) {
1612
1781
  const r = this.items.value.length;
1613
1782
  if (e < 0 || e >= r || t < 0 || t >= r) {
1614
- k.handle(
1783
+ V.handle(
1615
1784
  new Error(`ArrayNode.move: index out of bounds (from=${e}, to=${t}, length=${r})`),
1616
1785
  "ArrayNode.move",
1617
1786
  S.LOG
@@ -1639,7 +1808,7 @@ class W extends M {
1639
1808
  swap(e, t) {
1640
1809
  const r = this.items.value.length;
1641
1810
  if (e < 0 || e >= r || t < 0 || t >= r) {
1642
- k.handle(
1811
+ V.handle(
1643
1812
  new Error(`ArrayNode.swap: index out of bounds (a=${e}, b=${t}, length=${r})`),
1644
1813
  "ArrayNode.swap",
1645
1814
  S.LOG
@@ -1680,7 +1849,7 @@ class W extends M {
1680
1849
  }
1681
1850
  setValue(e, t) {
1682
1851
  this.clear(), e.forEach((r) => this.push(r)), t?.emitEvent !== !1 && this.validate().catch((r) => {
1683
- k.handle(r, "ArrayNode.setValue", S.LOG);
1852
+ V.handle(r, "ArrayNode.setValue", S.LOG);
1684
1853
  });
1685
1854
  }
1686
1855
  patchValue(e) {
@@ -2413,10 +2582,6 @@ function Ie(s) {
2413
2582
  }), r = be(e, s.validation), i = { model: e, form: t, ...r ? { validation: r } : {} };
2414
2583
  return s.setup?.(i), i;
2415
2584
  }
2416
- function Le(s) {
2417
- const [e] = ae(s), t = e.validation?.controller;
2418
- return z(() => t?.start(), [t]), e;
2419
- }
2420
2585
  function x(s) {
2421
2586
  return s == null ? !1 : typeof s == "object" && "value" in s && "setValue" in s && "getValue" in s && "validate" in s;
2422
2587
  }
@@ -2435,15 +2600,15 @@ function Se(s) {
2435
2600
  typeof s.push == "function" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
2436
2601
  typeof s.removeAt == "function";
2437
2602
  }
2438
- function Re(s) {
2603
+ function Le(s) {
2439
2604
  return Ee(s) ? "FieldNode" : _e(s) ? "GroupNode" : Se(s) ? "ArrayNode" : x(s) ? "FormNode" : "Unknown";
2440
2605
  }
2441
- var N = { exports: {} }, P = {};
2606
+ var F = { exports: {} }, P = {};
2442
2607
  var q;
2443
2608
  function Ae() {
2444
2609
  if (q) return P;
2445
2610
  q = 1;
2446
- var s = Y;
2611
+ var s = z;
2447
2612
  function e(o, f) {
2448
2613
  return o === f && (o !== 0 || 1 / o === 1 / f) || o !== o && f !== f;
2449
2614
  }
@@ -2530,16 +2695,16 @@ function we() {
2530
2695
  return v();
2531
2696
  }
2532
2697
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ < "u" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart == "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
2533
- var i = Y, n = typeof Object.is == "function" ? Object.is : s, a = i.useState, l = i.useEffect, d = i.useLayoutEffect, u = i.useDebugValue, h = !1, o = !1, f = typeof window > "u" || typeof window.document > "u" || typeof window.document.createElement > "u" ? r : e;
2698
+ var i = z, n = typeof Object.is == "function" ? Object.is : s, a = i.useState, l = i.useEffect, d = i.useLayoutEffect, u = i.useDebugValue, h = !1, o = !1, f = typeof window > "u" || typeof window.document > "u" || typeof window.document.createElement > "u" ? r : e;
2534
2699
  T.useSyncExternalStore = i.useSyncExternalStore !== void 0 ? i.useSyncExternalStore : f, typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ < "u" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop == "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
2535
2700
  })()), T;
2536
2701
  }
2537
2702
  var H;
2538
- function ke() {
2539
- return H || (H = 1, process.env.NODE_ENV === "production" ? N.exports = Ae() : N.exports = we()), N.exports;
2703
+ function Ve() {
2704
+ return H || (H = 1, process.env.NODE_ENV === "production" ? F.exports = Ae() : F.exports = we()), F.exports;
2540
2705
  }
2541
- var C = ke();
2542
- function Ve(s, e) {
2706
+ var C = Ve();
2707
+ function ke(s, e) {
2543
2708
  if (s === e) return !0;
2544
2709
  if (s.length !== e.length) return !1;
2545
2710
  for (let t = 0; t < s.length; t++)
@@ -2547,11 +2712,11 @@ function Ve(s, e) {
2547
2712
  return !0;
2548
2713
  }
2549
2714
  function $(s, e, t, r) {
2550
- const i = V(null), n = V(s);
2715
+ const i = k(null), n = k(s);
2551
2716
  n.current = s;
2552
- const a = V(e);
2717
+ const a = k(e);
2553
2718
  a.current = e;
2554
- const l = V(t);
2719
+ const l = k(t);
2555
2720
  if (l.current = t, i.current === null) {
2556
2721
  const h = {};
2557
2722
  for (const o in s)
@@ -2572,6 +2737,11 @@ function $(s, e, t, r) {
2572
2737
  h();
2573
2738
  });
2574
2739
  },
2740
+ // subscriptionKey намеренно не читается в теле — он здесь КЛЮЧ ИДЕНТИЧНОСТИ подписки (см. JSDoc
2741
+ // параметра). Убрать его (как предлагает автофикс) значит получить subscribe, созданный один раз
2742
+ // навсегда: подмена контрола на другой узел перестанет пересоздавать effect. Тот же приём ниже
2743
+ // у getSnapshot.
2744
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2575
2745
  [r]
2576
2746
  ), u = E(() => {
2577
2747
  const h = i.current, o = n.current, f = {};
@@ -2581,7 +2751,7 @@ function $(s, e, t, r) {
2581
2751
  for (const v of a.current) {
2582
2752
  const { key: p, useShallowArrayEqual: b } = v, y = f[p], w = h[p];
2583
2753
  if (b) {
2584
- if (!Ve(w, y)) {
2754
+ if (!ke(w, y)) {
2585
2755
  c = !0;
2586
2756
  break;
2587
2757
  }
@@ -2638,7 +2808,7 @@ function Oe(s) {
2638
2808
  );
2639
2809
  return $(e, t, r, s);
2640
2810
  }
2641
- function Fe(s) {
2811
+ function Ne(s) {
2642
2812
  const e = {
2643
2813
  value: s.value,
2644
2814
  length: s.length,
@@ -2675,7 +2845,7 @@ function Fe(s) {
2675
2845
  );
2676
2846
  return $(e, t, r, s);
2677
2847
  }
2678
- function Ne() {
2848
+ function Fe() {
2679
2849
  const s = E(
2680
2850
  () => ({
2681
2851
  value: [],
@@ -2692,12 +2862,12 @@ function Ne() {
2692
2862
  );
2693
2863
  return $({}, [], s);
2694
2864
  }
2695
- function $e(s) {
2865
+ function Re(s) {
2696
2866
  const e = s && "length" in s && "map" in s;
2697
- return s ? e ? Fe(s) : Oe(s) : Ne();
2867
+ return s ? e ? Ne(s) : Oe(s) : Fe();
2698
2868
  }
2699
- function Ge(s) {
2700
- const e = V({ value: s.value.value }), t = E(
2869
+ function $e(s) {
2870
+ const e = k({ value: s.value.value }), t = E(
2701
2871
  (i) => {
2702
2872
  let n = !0;
2703
2873
  return _(() => {
@@ -2715,8 +2885,8 @@ function Ge(s) {
2715
2885
  }, [s]);
2716
2886
  return C.useSyncExternalStore(t, r, r);
2717
2887
  }
2718
- function je(s) {
2719
- const e = V({ length: s.length.value }), t = E(
2888
+ function Ge(s) {
2889
+ const e = k({ length: s.length.value }), t = E(
2720
2890
  (i) => {
2721
2891
  let n = !0;
2722
2892
  return _(() => {
@@ -2734,12 +2904,12 @@ function je(s) {
2734
2904
  }, [s]);
2735
2905
  return C.useSyncExternalStore(t, r, r);
2736
2906
  }
2737
- function Be(s) {
2738
- const { model: e, schema: t, strategy: r, debounce: i, liveAfterSubmit: n } = s, a = oe(
2907
+ function je(s) {
2908
+ const { model: e, schema: t, strategy: r, debounce: i, liveAfterSubmit: n } = s, a = ae(
2739
2909
  () => D(e, t, { strategy: r, debounce: i, liveAfterSubmit: n }),
2740
2910
  [e, t, r, i, n]
2741
2911
  );
2742
- z(() => a.start(), [a]);
2912
+ Y(() => a.start(), [a]);
2743
2913
  const l = C.useSyncExternalStore(
2744
2914
  E((u) => a.validating.subscribe(u), [a]),
2745
2915
  () => a.validating.peek(),
@@ -2748,13 +2918,17 @@ function Be(s) {
2748
2918
  ), d = E(() => a.validate(), [a]);
2749
2919
  return { submit: d, validate: d, isValidating: l };
2750
2920
  }
2921
+ function Be(s) {
2922
+ const [e] = oe(s), t = e.validation?.controller;
2923
+ return Y(() => t?.start(), [t]), e;
2924
+ }
2751
2925
  const Ue = Object.freeze({ runtime: "reformer-core", v: 1 });
2752
2926
  export {
2753
2927
  W as ArrayNode,
2754
2928
  Ue as CORE_RUNTIME_TOKEN,
2755
2929
  S as ErrorStrategy,
2756
2930
  de as FieldNode,
2757
- k as FormErrorHandler,
2931
+ V as FormErrorHandler,
2758
2932
  M as FormNode,
2759
2933
  he as FormSubmitter,
2760
2934
  A as GroupNode,
@@ -2762,36 +2936,37 @@ export {
2762
2936
  ve as NodeFactory,
2763
2937
  L as SubscriptionManager,
2764
2938
  be as buildValidation,
2765
- Je as computeFrom,
2766
- Qe as copyFrom,
2939
+ Xe as computeFrom,
2940
+ Ze as copyFrom,
2767
2941
  Ie as createCoreForm,
2768
2942
  ye as createForm,
2769
2943
  Z as createFormFromModel,
2770
2944
  ee as createModel,
2771
- ut as disableWhen,
2772
- dt as enableWhen,
2773
- ot as getNodeForSignal,
2774
- Re as getNodeType,
2945
+ ct as disableWhen,
2946
+ Ke as eachLeafSignal,
2947
+ ht as enableWhen,
2948
+ ut as getNodeForSignal,
2949
+ Le as getNodeType,
2775
2950
  Se as isArrayNode,
2776
2951
  G as isDerived,
2777
2952
  Ee as isFieldNode,
2778
2953
  x as isFormNode,
2779
2954
  _e as isGroupNode,
2780
- Ke as isModelContainerSignal,
2781
- He as markDerived,
2955
+ ze as isModelContainerSignal,
2956
+ Ye as markDerived,
2782
2957
  se as registerSignalNode,
2783
- Xe as resetWhen,
2784
- Ze as revalidateWhen,
2785
- et as runOutsideEffect,
2786
- tt as safeCallback,
2787
- st as safeDebouncedCallback,
2788
- rt as syncFields,
2789
- it as transformValue,
2790
- Ye as unmarkDerived,
2791
- je as useArrayLength,
2792
- Le as useFormBundle,
2793
- $e as useFormControl,
2794
- Ge as useFormControlValue,
2795
- Be as useFormValidation,
2796
- nt as watchField
2958
+ et as resetWhen,
2959
+ tt as revalidateWhen,
2960
+ st as runOutsideEffect,
2961
+ rt as safeCallback,
2962
+ it as safeDebouncedCallback,
2963
+ nt as syncFields,
2964
+ at as transformValue,
2965
+ Je as unmarkDerived,
2966
+ Ge as useArrayLength,
2967
+ Be as useFormBundle,
2968
+ Re as useFormControl,
2969
+ $e as useFormControlValue,
2970
+ je as useFormValidation,
2971
+ ot as watchField
2797
2972
  };
@@ -1,18 +1,4 @@
1
1
  import { FormModel, PathAwareSignal } from './types';
2
- /**
3
- * Узел дерева `model.$` — контейнер (группа/массив), а не лист?
4
- *
5
- * Контейнерный узел структурно совместим с `ReadonlySignal` (`peek`/`value`/`subscribe`), поэтому
6
- * duck-typing «есть `peek` ⇒ это лист» на нём даёт ложное срабатывание. Этот guard — надёжный
7
- * способ различить: обходчикам дерева нужно спускаться в контейнер, а не читать его целиком.
8
- *
9
- * @group Model
10
- * @example
11
- * ```typescript
12
- * const isLeaf = (v: unknown) => isSignalLike(v) && !isModelContainerSignal(v);
13
- * ```
14
- */
15
- export declare function isModelContainerSignal(value: unknown): boolean;
16
2
  /**
17
3
  * Обойти ВСЕ листовые сигналы модели (включая элементы массивов), вызвав `visit` на каждом.
18
4
  *
@@ -1,32 +1,31 @@
1
1
  /**
2
- * `@reformer/core/state` — низкоуровневый реактивный **state-субстрат** (M1) и barrel модуля `state`.
2
+ * `@reformer/core/model` — низкоуровневый реактивный субстрат (M1) и barrel модуля `model`.
3
3
  *
4
4
  * Это «прокси-объект с сигналами» и инструментарий для построения доменных модулей поверх него
5
5
  * (form, table, …). Модуль СТРОГО реактивный: НИЧЕГО связанного с формами/валидацией/схемами здесь
6
- * нет — только модель, value-операции, producer-флаг и утилиты субстрата. Граница state⇏form
7
- * зафиксирована ESLint-правилом (`no-restricted-imports` на `src/state/**`).
6
+ * нет — только модель, value-операции, producer-флаг и утилиты субстрата. Граница model⇏form
7
+ * зафиксирована ESLint-правилом (`no-restricted-imports` на `src/model/**`).
8
8
  *
9
9
  * Реактивный рантайм (`signal/computed/effect/…`) живёт в отдельном subpath `@reformer/core/signals`
10
10
  * (единый владелец `@preact/signals-core`) — импортируй его оттуда; здесь он НЕ реэкспортируется,
11
11
  * чтобы зонтичный barrel `.` не разрастался рантаймом.
12
12
  *
13
- * Состав (реэкспорты — из тех же файлов, что использует зонтик `.`, поэтому `.` и `/state` — один
13
+ * Состав (реэкспорты — из тех же файлов, что использует зонтик `.`, поэтому `.` и `/model` — один
14
14
  * module-инстанс: общий `derived`-WeakMap, единая идентичность `Signal`):
15
15
  * - **модель** — `createModel` + типы `FormModel`/`ModelArray`/… + `PathAwareSignal`;
16
+ * - **обход листьев** — `eachLeafSignal` (подписка «любое поле изменилось»);
16
17
  * - **value-операции** (реактивные правила) — `computeFrom`/`copyFrom`/`watchField`/`transformValue`/
17
18
  * `resetWhen`/`syncFields`/`revalidateWhen`;
18
19
  * - **producer-owned флаг** — `markDerived`/`isDerived`/`unmarkDerived`;
19
- * - **утилиты субстрата** — `runOutsideEffect`/`safeCallback`/`safeDebouncedCallback`,
20
- * `SubscriptionManager`.
20
+ * - **утилиты субстрата** — `runOutsideEffect`/`safeCallback`/`safeDebouncedCallback`.
21
21
  *
22
- * @group State
23
- * @module state
22
+ * @group Model
23
+ * @module model
24
24
  */
25
- export { createModel } from './form-model';
25
+ export { createModel, eachLeafSignal } from './create-model';
26
26
  export type { FormModel, ModelArray, ModelArraySignals, ModelGroupSignals, ModelObject, ModelValue, ModelSignals, ModelApi, PathAwareSignal, } from './types';
27
- export { isModelContainerSignal } from './form-model';
27
+ export { isModelContainerSignal } from './model-signals-proxy';
28
28
  export { computeFrom, copyFrom, watchField, transformValue, resetWhen, syncFields, revalidateWhen, } from './behaviors-value';
29
29
  export type { BehaviorCleanup } from './behaviors-value';
30
30
  export { markDerived, isDerived, unmarkDerived } from './derived-registry';
31
31
  export { runOutsideEffect, safeCallback, safeDebouncedCallback } from './safe-effect';
32
- export { SubscriptionManager } from './subscription-manager';
@@ -0,0 +1,60 @@
1
+ import { Signal } from '@preact/signals-core';
2
+ import { PathAwareSignal } from './types';
3
+ export declare const isIndexKey: (key: string) => boolean;
4
+ export type ModelNode = LeafNode | GroupNode | ArrayNode;
5
+ declare class LeafNode {
6
+ path: string;
7
+ readonly kind: "leaf";
8
+ readonly signal: PathAwareSignal<unknown>;
9
+ private initial;
10
+ constructor(initial: unknown, path: string);
11
+ rebase(path: string): void;
12
+ /** Реактивное чтение (внутри effect/computed создаёт зависимость). */
13
+ read(): unknown;
14
+ /** Нереактивный снимок. */
15
+ peek(): unknown;
16
+ set(value: unknown): void;
17
+ resetToInitial(): void;
18
+ captureInitial(): void;
19
+ dirty(): boolean;
20
+ }
21
+ export declare class GroupNode {
22
+ path: string;
23
+ readonly kind: "group";
24
+ readonly children: Map<string, ModelNode>;
25
+ constructor(initial: Record<string, unknown>, path: string);
26
+ rebase(path: string): void;
27
+ /** Реактивное чтение поддерева (внутри effect/computed подписывает на все листья группы). */
28
+ read(): Record<string, unknown>;
29
+ peek(): Record<string, unknown>;
30
+ set(value: unknown): void;
31
+ resetToInitial(): void;
32
+ captureInitial(): void;
33
+ dirty(): boolean;
34
+ }
35
+ export declare class ArrayNode {
36
+ path: string;
37
+ readonly kind: "array";
38
+ readonly items: Signal<ModelNode[]>;
39
+ private initial;
40
+ constructor(initial: unknown[], path: string);
41
+ rebase(path: string): void;
42
+ private reindex;
43
+ push(value: unknown): void;
44
+ insertAt(index: number, value: unknown): void;
45
+ removeAt(index: number): void;
46
+ move(from: number, to: number): void;
47
+ swap(a: number, b: number): void;
48
+ clear(): void;
49
+ /**
50
+ * Реактивное чтение массива. Читаем `items.value` (а не `.peek()`) — внутри effect/computed это
51
+ * подписка на СОСТАВ массива, поэтому push/removeAt/move ретригерят наравне с правкой элемента.
52
+ */
53
+ read(): unknown[];
54
+ peek(): unknown[];
55
+ set(value: unknown): void;
56
+ resetToInitial(): void;
57
+ captureInitial(): void;
58
+ dirty(): boolean;
59
+ }
60
+ export {};